summaryrefslogtreecommitdiff
path: root/posix
diff options
context:
space:
mode:
authorAndreas Schwab <schwab@redhat.com>2010-02-01 12:22:55 +0100
committerAndreas Schwab <schwab@redhat.com>2010-02-01 12:22:55 +0100
commit5229ffc381ccf5897ca83be5891051c7607638f6 (patch)
tree0acfe4328875230186f82ff09a1e07e1df9373d0 /posix
parentb675f5a8621ca898e64d0bf51d7fa1469322f861 (diff)
parentb34e12e22c00d74ee549ae9ac304f64d1d6374d5 (diff)
Merge remote branch 'origin/master' into fedora/master
Diffstat (limited to 'posix')
-rw-r--r--posix/regex_internal.c34
-rw-r--r--posix/regexec.c55
2 files changed, 65 insertions, 24 deletions
diff --git a/posix/regex_internal.c b/posix/regex_internal.c
index ff28e5fcb9..8183a29bf6 100644
--- a/posix/regex_internal.c
+++ b/posix/regex_internal.c
@@ -133,7 +133,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;
@@ -482,18 +489,18 @@ 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))
+ if (BE ((ssize_t) mbclen <= 0, 0))
{
/* We treat these cases as a single byte character. */
if (mbclen == 0 || remain_len == 0)
@@ -503,10 +510,12 @@ 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;
}
- *last_wc = (wint_t) wc;
+ *last_wc = wc;
return rawbuf_idx;
}
#endif /* RE_ENABLE_I18N */
@@ -694,7 +703,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 +732,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). */
@@ -1404,8 +1411,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);
diff --git a/posix/regexec.c b/posix/regexec.c
index b8db74062b..f87701672b 100644
--- a/posix/regexec.c
+++ b/posix/regexec.c
@@ -368,16 +368,16 @@ re_search_2_stub (bufp, string1, length1, string2, length2, start, range, regs,
const char *str;
int rval;
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;
/* Concatenate the strings. */
if (length2 > 0)
if (length1 > 0)
{
- char *s = re_malloc (char, len);
+ s = re_malloc (char, len);
if (BE (s == NULL, 0))
return -2;
@@ -388,17 +388,14 @@ re_search_2_stub (bufp, string1, length1, string2, length2, start, range, regs,
memcpy (s + length1, string2, length2);
#endif
str = s;
- free_str = 1;
}
else
str = string2;
else
str = string1;
- rval = re_search_stub (bufp, str, len, start, range, stop, regs,
- ret_len);
- if (free_str)
- re_free ((char *) str);
+ rval = re_search_stub (bufp, str, len, start, range, stop, regs, ret_len);
+ re_free (s);
return rval;
}
@@ -512,9 +509,14 @@ re_copy_regs (regs, pmatch, nregs, regs_allocated)
if (regs_allocated == REGS_UNALLOCATED)
{ /* No. So allocate them with malloc. */
regs->start = re_malloc (regoff_t, need_regs);
- regs->end = re_malloc (regoff_t, need_regs);
- if (BE (regs->start == NULL, 0) || BE (regs->end == NULL, 0))
+ if (BE (regs->start == NULL, 0))
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;
}
else if (regs_allocated == REGS_REALLOCATE)
@@ -524,9 +526,15 @@ re_copy_regs (regs, pmatch, nregs, regs_allocated)
if (BE (need_regs > regs->num_regs, 0))
{
regoff_t *new_start = re_realloc (regs->start, regoff_t, need_regs);
- regoff_t *new_end = re_realloc (regs->end, regoff_t, need_regs);
- if (BE (new_start == NULL, 0) || BE (new_end == NULL, 0))
+ regoff_t *new_end;
+ if (BE (new_start == NULL, 0))
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->end = new_end;
regs->num_regs = need_regs;
@@ -694,6 +702,13 @@ re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
multi character collating element. */
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);
if (BE (mctx.state_log == NULL, 0))
{
@@ -952,6 +967,11 @@ prune_impossible_nodes (mctx)
#endif
match_last = mctx->match_last;
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);
if (BE (sifted_states == NULL, 0))
{
@@ -3362,6 +3382,13 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
if (BE (err != REG_NOERROR, 0))
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
+ ndests * 3 * sizeof (re_dfastate_t *)))
dest_states = (re_dfastate_t **)
@@ -4077,6 +4104,10 @@ extend_buffers (re_match_context_t *mctx)
reg_errcode_t ret;
re_string_t *pstr = &mctx->input;
+ /* Avoid overflow. */
+ if (BE (INT_MAX / 2 / sizeof (re_dfastate_t *) <= pstr->bufs_len, 0))
+ return REG_ESPACE;
+
/* Double the lengthes of the buffers. */
ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
if (BE (ret != REG_NOERROR, 0))