diff options
Diffstat (limited to 'regex_internal.c')
-rw-r--r-- | regex_internal.c | 108 |
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; } |