aboutsummaryrefslogtreecommitdiffstats
path: root/regex_internal.c
diff options
context:
space:
mode:
Diffstat (limited to 'regex_internal.c')
-rw-r--r--regex_internal.c108
1 files changed, 65 insertions, 43 deletions
diff --git a/regex_internal.c b/regex_internal.c
index 2b07332f..dad17a81 100644
--- a/regex_internal.c
+++ b/regex_internal.c
@@ -1,5 +1,5 @@
/* Extended regular expression matching and search library.
- Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ Copyright (C) 2002-2006, 2010 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
@@ -29,6 +29,15 @@ static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa,
const re_node_set *nodes,
unsigned int context,
unsigned int hash) internal_function;
+
+#ifdef GAWK
+#undef MAX /* safety */
+static int
+MAX(size_t a, size_t b)
+{
+ return (a > b ? a : b);
+}
+#endif
/* Functions for string operation. */
@@ -133,7 +142,14 @@ re_string_realloc_buffers (re_string_t *pstr, int new_buf_len)
#ifdef RE_ENABLE_I18N
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))
return REG_ESPACE;
pstr->wcs = new_wcs;
@@ -423,8 +439,8 @@ build_wcs_upper_buffer (re_string_t *pstr)
src_idx += mbclen;
continue;
}
- else
- memcpy (pstr->mbs + byte_idx, p, mbclen);
+ else
+ memcpy (pstr->mbs + byte_idx, p, mbclen);
}
else
memcpy (pstr->mbs + byte_idx, p, mbclen);
@@ -482,16 +498,16 @@ re_string_skip_chars (re_string_t *pstr, int new_raw_idx, wint_t *last_wc)
mbstate_t prev_st;
int rawbuf_idx;
size_t mbclen;
- wchar_t wc = WEOF;
+ wint_t wc = WEOF;
/* Skip the characters which are not necessary to check. */
for (rawbuf_idx = pstr->raw_mbs_idx + pstr->valid_raw_len;
rawbuf_idx < new_raw_idx;)
{
- int remain_len;
- remain_len = pstr->len - rawbuf_idx;
+ wchar_t wc2;
+ int remain_len = pstr->len - rawbuf_idx;
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);
if (BE (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0, 0))
{
@@ -503,6 +519,8 @@ re_string_skip_chars (re_string_t *pstr, int new_raw_idx, wint_t *last_wc)
mbclen = 1;
pstr->cur_state = prev_st;
}
+ else
+ wc = (wint_t) wc2;
/* Then proceed the next character. */
rawbuf_idx += mbclen;
}
@@ -694,7 +712,7 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
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
byte other than 0x80 - 0xbf. */
@@ -723,13 +741,11 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
unsigned char buf[6];
size_t mbclen;
- q = p;
if (BE (pstr->trans != NULL, 0))
{
int i = mlen < 6 ? mlen : 6;
while (--i >= 0)
buf[i] = pstr->trans[p[i]];
- q = buf;
}
/* XXX Don't use mbrtowc, we know which conversion
to use (UTF-8 -> UCS4). */
@@ -1059,7 +1075,7 @@ re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
int new_alloc = src1->nelem + src2->nelem + dest->alloc;
int *new_elems = re_realloc (dest->elems, int, new_alloc);
if (BE (new_elems == NULL, 0))
- return REG_ESPACE;
+ return REG_ESPACE;
dest->elems = new_elems;
dest->alloc = new_alloc;
}
@@ -1078,8 +1094,8 @@ re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
while (id >= 0 && dest->elems[id] > src1->elems[i1])
--id;
- if (id < 0 || dest->elems[id] != src1->elems[i1])
- dest->elems[--sbase] = src1->elems[i1];
+ if (id < 0 || dest->elems[id] != src1->elems[i1])
+ dest->elems[--sbase] = src1->elems[i1];
if (--i1 < 0 || --i2 < 0)
break;
@@ -1109,20 +1125,20 @@ re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
if (delta > 0 && id >= 0)
for (;;)
{
- if (dest->elems[is] > dest->elems[id])
- {
- /* Copy from the top. */
- dest->elems[id + delta--] = dest->elems[is--];
- if (delta == 0)
- break;
- }
- else
- {
- /* Slide from the bottom. */
- dest->elems[id + delta] = dest->elems[id];
- if (--id < 0)
- break;
- }
+ if (dest->elems[is] > dest->elems[id])
+ {
+ /* Copy from the top. */
+ dest->elems[id + delta--] = dest->elems[is--];
+ if (delta == 0)
+ break;
+ }
+ else
+ {
+ /* Slide from the bottom. */
+ dest->elems[id + delta] = dest->elems[id];
+ if (--id < 0)
+ break;
+ }
}
/* Copy remaining SRC elements. */
@@ -1217,11 +1233,11 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src)
is = src->nelem - 1, id = dest->nelem - 1; is >= 0 && id >= 0; )
{
if (dest->elems[id] == src->elems[is])
- is--, id--;
+ is--, id--;
else if (dest->elems[id] < src->elems[is])
- dest->elems[--sbase] = src->elems[is--];
+ dest->elems[--sbase] = src->elems[is--];
else /* if (dest->elems[id] > src->elems[is]) */
- --id;
+ --id;
}
if (is >= 0)
@@ -1243,21 +1259,21 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src)
for (;;)
{
if (dest->elems[is] > dest->elems[id])
- {
+ {
/* Copy from the top. */
- dest->elems[id + delta--] = dest->elems[is--];
+ dest->elems[id + delta--] = dest->elems[is--];
if (delta == 0)
break;
}
else
- {
- /* Slide from the bottom. */
- dest->elems[id + delta] = dest->elems[id];
+ {
+ /* Slide from the bottom. */
+ dest->elems[id + delta] = dest->elems[id];
if (--id < 0)
{
/* Copy remaining SRC elements. */
memcpy (dest->elems, dest->elems + sbase,
- delta * sizeof (int));
+ delta * sizeof (int));
break;
}
}
@@ -1309,12 +1325,12 @@ re_node_set_insert (re_node_set *set, int elem)
{
idx = 0;
for (idx = set->nelem; idx > 0; idx--)
- set->elems[idx] = set->elems[idx - 1];
+ set->elems[idx] = set->elems[idx - 1];
}
else
{
for (idx = set->nelem; set->elems[idx - 1] > elem; idx--)
- set->elems[idx] = set->elems[idx - 1];
+ set->elems[idx] = set->elems[idx - 1];
}
/* Insert the new element. */
@@ -1413,8 +1429,11 @@ re_dfa_add_node (re_dfa_t *dfa, re_token_t token)
re_node_set *new_edests, *new_eclosures;
re_token_t *new_nodes;
- /* Avoid overflows. */
- if (BE (new_nodes_alloc < dfa->nodes_alloc, 0))
+ /* Avoid overflows in realloc. */
+ 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;
new_nodes = re_realloc (dfa->nodes, re_token_t, new_nodes_alloc);
@@ -1563,7 +1582,8 @@ register_state (const re_dfa_t *dfa, re_dfastate_t *newstate,
{
int elem = newstate->nodes.elems[i];
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);
@@ -1700,7 +1720,9 @@ create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
free_state (newstate);
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;
newstate->has_constraint = 1;
}