-# $Id: srclist.txt,v 1.100 2005-09-02 12:27:28 karl Exp $
+# $Id: srclist.txt,v 1.101 2005-09-02 22:54:59 eggert Exp $
# Files for which we are not the source. See ./srclistvars.sh for the
# variable definitions.
# http://sources.redhat.com/bugzilla/show_bug.cgi?id=1281
# http://sources.redhat.com/bugzilla/show_bug.cgi?id=1282
# http://sources.redhat.com/bugzilla/show_bug.cgi?id=1285
+# http://sources.redhat.com/bugzilla/show_bug.cgi?id=1291
#$LIBCSRC/posix/regcomp.c lib gpl
#
# http://sources.redhat.com/bugzilla/show_bug.cgi?id=1238
# http://sources.redhat.com/bugzilla/show_bug.cgi?id=1285
# http://sources.redhat.com/bugzilla/show_bug.cgi?id=1286
# http://sources.redhat.com/bugzilla/show_bug.cgi?id=1287
+# http://sources.redhat.com/bugzilla/show_bug.cgi?id=1291
#$LIBCSRC/posix/regex_internal.c lib gpl
#
# http://sources.redhat.com/bugzilla/show_bug.cgi?id=1054
# http://sources.redhat.com/bugzilla/show_bug.cgi?id=1278
# http://sources.redhat.com/bugzilla/show_bug.cgi?id=1281
# http://sources.redhat.com/bugzilla/show_bug.cgi?id=1285
+# http://sources.redhat.com/bugzilla/show_bug.cgi?id=1291
#$LIBCSRC/posix/regex_internal.h lib gpl
#
# http://sources.redhat.com/bugzilla/show_bug.cgi?id=1216
+2005-09-02 Paul Eggert <eggert@cs.ucla.edu>
+
+ Check for arithmetic overflow when calculating sizes, to prevent
+ some buffer-overflow issues. These patches are conservative, in the
+ sense that when I couldn't determine whether an overflow was possible,
+ I inserted a run-time check.
+ * regex_internal.h (re_xmalloc, re_xrealloc, re_x2realloc): New macros.
+ (SIZE_MAX) [!defined SIZE_MAX]: New macro.
+ (re_alloc_oversized, re_x2alloc_oversized, re_xnmalloc):
+ (re_xnrealloc, re_x2nrealloc): New inline functions.
+ * lib/regcomp.c (init_dfa, analyze, build_range_exp, parse_bracket_exp):
+ (build_equiv_class, build_charclass): Check for arithmetic overflow
+ in size expression calculations.
+ * lib/regex_internal.c (re_string_realloc_buffers):
+ (build_wcs_upper_buffer, re_node_set_add_intersect):
+ (re_node_set_init_union, re_node_set_insert, re_node_set_insert_last):
+ (re_dfa_add_node, register_state): Likewise.
+ * lib/regexec.c (re_search_stub, re_copy_regs, re_search_internal):
+ (prune_impossible_nodes, push_fail_stack, set_regs, check_arrival):
+ (build_trtable, extend_buffers, match_ctx_init, match_ctx_add_entry):
+ (match_ctx_add_subtop, match_ctx_add_sublast): Likewise.
+
2005-09-01 Paul Eggert <eggert@cs.ucla.edu>
* glob.c (GET_LOGIN_NAME_MAX): Renamed from LOGIN_NAME_MAX,
dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE;
dfa->nodes_alloc = pat_len + 1;
- dfa->nodes = re_malloc (re_token_t, dfa->nodes_alloc);
+ dfa->nodes = re_xmalloc (re_token_t, dfa->nodes_alloc);
/* table_size = 2 ^ ceil(log pat_len) */
for (table_size = 1; table_size <= pat_len; table_size <<= 1)
/* Allocate arrays. */
dfa->nexts = re_malloc (Idx, dfa->nodes_alloc);
dfa->org_indices = re_malloc (Idx, dfa->nodes_alloc);
- dfa->edests = re_malloc (re_node_set, dfa->nodes_alloc);
+ dfa->edests = re_xmalloc (re_node_set, dfa->nodes_alloc);
dfa->eclosures = re_malloc (re_node_set, dfa->nodes_alloc);
if (BE (dfa->nexts == NULL || dfa->org_indices == NULL || dfa->edests == NULL
|| dfa->eclosures == NULL, 0))
return REG_ESPACE;
- dfa->subexp_map = re_malloc (Idx, preg->re_nsub);
+ dfa->subexp_map = re_xmalloc (Idx, preg->re_nsub);
if (dfa->subexp_map != NULL)
{
Idx i;
if ((!preg->re_no_sub && preg->re_nsub > 0 && dfa->has_plural_match)
|| dfa->nbackref)
{
- dfa->inveclosures = re_malloc (re_node_set, dfa->nodes_len);
+ dfa->inveclosures = re_xmalloc (re_node_set, dfa->nodes_len);
if (BE (dfa->inveclosures == NULL, 0))
return REG_ESPACE;
ret = calc_inveclosure (dfa);
wchar_t *new_array_start, *new_array_end;
Idx new_nranges;
- /* +1 in case of mbcset->nranges is 0. */
- new_nranges = 2 * mbcset->nranges + 1;
+ new_nranges = mbcset->nranges;
/* Use realloc since mbcset->range_starts and mbcset->range_ends
are NULL if *range_alloc == 0. */
- new_array_start = re_realloc (mbcset->range_starts, wchar_t,
- new_nranges);
+ new_array_start = re_x2realloc (mbcset->range_starts, wchar_t,
+ &new_nranges);
new_array_end = re_realloc (mbcset->range_ends, wchar_t,
new_nranges);
uint32_t *new_array_end;
Idx new_nranges;
- /* +1 in case of mbcset->nranges is 0. */
- new_nranges = 2 * mbcset->nranges + 1;
- new_array_start = re_realloc (mbcset->range_starts, uint32_t,
- new_nranges);
+ new_nranges = mbcset->nranges;
+ new_array_start = re_x2realloc (mbcset->range_starts, uint32_t,
+ &new_nranges);
new_array_end = re_realloc (mbcset->range_ends, uint32_t,
new_nranges);
if (BE (*coll_sym_alloc == mbcset->ncoll_syms, 0))
{
/* Not enough, realloc it. */
- /* +1 in case of mbcset->ncoll_syms is 0. */
- Idx new_coll_sym_alloc = 2 * mbcset->ncoll_syms + 1;
+ Idx new_coll_sym_alloc = mbcset->ncoll_syms;
/* Use realloc since mbcset->coll_syms is NULL
if *alloc == 0. */
- int32_t *new_coll_syms = re_realloc (mbcset->coll_syms, int32_t,
- new_coll_sym_alloc);
+ int32_t *new_coll_syms = re_x2realloc (mbcset->coll_syms, int32_t,
+ &new_coll_sym_alloc);
if (BE (new_coll_syms == NULL, 0))
return REG_ESPACE;
mbcset->coll_syms = new_coll_syms;
{
wchar_t *new_mbchars;
/* Not enough, realloc it. */
- /* +1 in case of mbcset->nmbchars is 0. */
- mbchar_alloc = 2 * mbcset->nmbchars + 1;
+ mbchar_alloc = mbcset->nmbchars;
/* Use realloc since array is NULL if *alloc == 0. */
- new_mbchars = re_realloc (mbcset->mbchars, wchar_t,
- mbchar_alloc);
+ new_mbchars = re_x2realloc (mbcset->mbchars, wchar_t,
+ &mbchar_alloc);
if (BE (new_mbchars == NULL, 0))
goto parse_bracket_exp_espace;
mbcset->mbchars = new_mbchars;
if (BE (*equiv_class_alloc == mbcset->nequiv_classes, 0))
{
/* Not enough, realloc it. */
- /* +1 in case of mbcset->nequiv_classes is 0. */
- Idx new_equiv_class_alloc = 2 * mbcset->nequiv_classes + 1;
+ Idx new_equiv_class_alloc = mbcset->nequiv_classes;
/* Use realloc since the array is NULL if *alloc == 0. */
- int32_t *new_equiv_classes = re_realloc (mbcset->equiv_classes,
- int32_t,
- new_equiv_class_alloc);
+ int32_t *new_equiv_classes = re_x2realloc (mbcset->equiv_classes,
+ int32_t,
+ &new_equiv_class_alloc);
if (BE (new_equiv_classes == NULL, 0))
return REG_ESPACE;
mbcset->equiv_classes = new_equiv_classes;
if (BE (*char_class_alloc == mbcset->nchar_classes, 0))
{
/* Not enough, realloc it. */
- /* +1 in case of mbcset->nchar_classes is 0. */
- Idx new_char_class_alloc = 2 * mbcset->nchar_classes + 1;
+ Idx new_char_class_alloc = mbcset->nchar_classes;
/* Use realloc since array is NULL if *alloc == 0. */
- wctype_t *new_char_classes = re_realloc (mbcset->char_classes, wctype_t,
- new_char_class_alloc);
+ wctype_t *new_char_classes = re_x2realloc (mbcset->char_classes, wctype_t,
+ &new_char_class_alloc);
if (BE (new_char_classes == NULL, 0))
return REG_ESPACE;
mbcset->char_classes = new_char_classes;
#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 = re_xrealloc (pstr->wcs, wint_t, new_buf_len);
if (BE (new_wcs == NULL, 0))
return REG_ESPACE;
pstr->wcs = new_wcs;
if (pstr->offsets != NULL)
{
- Idx *new_offsets = re_realloc (pstr->offsets, Idx, new_buf_len);
+ Idx *new_offsets = re_xrealloc (pstr->offsets, Idx, new_buf_len);
if (BE (new_offsets == NULL, 0))
return REG_ESPACE;
pstr->offsets = new_offsets;
if (pstr->offsets == NULL)
{
- pstr->offsets = re_malloc (Idx, pstr->bufs_len);
+ pstr->offsets = re_xmalloc (Idx, pstr->bufs_len);
if (pstr->offsets == NULL)
return REG_ESPACE;
{
set->alloc = size;
set->nelem = 0;
- set->elems = re_malloc (Idx, size);
+ set->elems = re_xmalloc (Idx, size);
if (BE (set->elems == NULL, 0))
return REG_ESPACE;
return REG_NOERROR;
if (src1->nelem + src2->nelem + dest->nelem > dest->alloc)
{
Idx new_alloc = src1->nelem + src2->nelem + dest->alloc;
- Idx *new_elems = re_realloc (dest->elems, Idx, new_alloc);
+ Idx *new_elems;
+ if (sizeof (Idx) < 3
+ && (new_alloc < dest->alloc
+ || ((Idx) (src1->nelem + src2->nelem) < src1->nelem)))
+ return REG_ESPACE;
+ new_elems = re_xrealloc (dest->elems, Idx, new_alloc);
if (BE (new_elems == NULL, 0))
return REG_ESPACE;
dest->elems = new_elems;
if (src1 != NULL && src1->nelem > 0 && src2 != NULL && src2->nelem > 0)
{
dest->alloc = src1->nelem + src2->nelem;
- dest->elems = re_malloc (Idx, dest->alloc);
+ if (sizeof (Idx) < 2 && dest->alloc < src1->nelem)
+ return REG_ESPACE;
+ dest->elems = re_xmalloc (Idx, dest->alloc);
if (BE (dest->elems == NULL, 0))
return REG_ESPACE;
}
Idx is, id, sbase, delta;
if (src == NULL || src->nelem == 0)
return REG_NOERROR;
+ if (sizeof (Idx) < 3
+ && ((Idx) (2 * src->nelem) < src->nelem
+ || (Idx) (2 * src->nelem + dest->nelem) < dest->nelem))
+ return REG_ESPACE;
if (dest->alloc < 2 * src->nelem + dest->nelem)
{
- Idx new_alloc = 2 * (src->nelem + dest->alloc);
- Idx *new_buffer = re_realloc (dest->elems, Idx, new_alloc);
+ Idx new_alloc = src->nelem + dest->alloc;
+ Idx *new_buffer;
+ if (sizeof (Idx) < 4 && new_alloc < dest->alloc)
+ return REG_ESPACE;
+ new_buffer = re_x2realloc (dest->elems, Idx, &new_alloc);
if (BE (new_buffer == NULL, 0))
return REG_ESPACE;
dest->elems = new_buffer;
/* Realloc if we need. */
if (set->alloc == set->nelem)
{
- Idx *new_elems;
- set->alloc = set->alloc * 2;
- new_elems = re_realloc (set->elems, Idx, set->alloc);
+ Idx *new_elems = re_x2realloc (set->elems, Idx, &set->alloc);
if (BE (new_elems == NULL, 0))
return false;
set->elems = new_elems;
if (set->alloc == set->nelem)
{
Idx *new_elems;
- set->alloc = (set->alloc + 1) * 2;
- new_elems = re_realloc (set->elems, Idx, set->alloc);
+ new_elems = re_x2realloc (set->elems, Idx, &set->alloc);
if (BE (new_elems == NULL, 0))
return false;
set->elems = new_elems;
int type = token.type;
if (BE (dfa->nodes_len >= dfa->nodes_alloc, 0))
{
- Idx new_nodes_alloc = dfa->nodes_alloc * 2;
+ Idx new_nodes_alloc = dfa->nodes_alloc;
Idx *new_nexts, *new_indices;
re_node_set *new_edests, *new_eclosures;
- re_token_t *new_nodes = re_realloc (dfa->nodes, re_token_t,
- new_nodes_alloc);
+ re_token_t *new_nodes = re_x2realloc (dfa->nodes, re_token_t,
+ &new_nodes_alloc);
if (BE (new_nodes == NULL, 0))
return REG_MISSING;
dfa->nodes = new_nodes;
new_nexts = re_realloc (dfa->nexts, Idx, new_nodes_alloc);
new_indices = re_realloc (dfa->org_indices, Idx, new_nodes_alloc);
- new_edests = re_realloc (dfa->edests, re_node_set, new_nodes_alloc);
+ new_edests = re_xrealloc (dfa->edests, re_node_set, new_nodes_alloc);
new_eclosures = re_realloc (dfa->eclosures, re_node_set, new_nodes_alloc);
if (BE (new_nexts == NULL || new_indices == NULL
|| new_edests == NULL || new_eclosures == NULL, 0))
spot = dfa->state_table + (hash & dfa->state_hash_mask);
if (BE (spot->alloc <= spot->num, 0))
{
- Idx new_alloc = 2 * spot->num + 2;
- re_dfastate_t **new_array = re_realloc (spot->array, re_dfastate_t *,
- new_alloc);
+ Idx new_alloc = spot->num;
+ re_dfastate_t **new_array = re_x2realloc (spot->array, re_dfastate_t *,
+ &new_alloc);
if (BE (new_array == NULL, 0))
return REG_ESPACE;
spot->array = new_array;
#endif
#define re_malloc(t,n) ((t *) malloc ((n) * sizeof (t)))
+#define re_xmalloc(t,n) ((t *) re_xnmalloc (n, sizeof (t)))
#define re_calloc(t,n) ((t *) calloc (n, sizeof (t)))
#define re_realloc(p,t,n) ((t *) realloc (p, (n) * sizeof (t)))
+#define re_xrealloc(p,t,n) ((t *) re_xnrealloc (p, n, sizeof (t)))
+#define re_x2realloc(p,t,pn) ((t *) re_x2nrealloc (p, pn, sizeof (t)))
#define re_free(p) free (p)
+#ifndef SIZE_MAX
+# define SIZE_MAX ((size_t) -1)
+#endif
+
+/* Return true if an array of N objects, each of size S, cannot exist
+ due to size arithmetic overflow. S must be nonzero. */
+static inline bool
+re_alloc_oversized (size_t n, size_t s)
+{
+ return BE (SIZE_MAX / s < n, 0);
+}
+
+/* Return true if an array of (2 * N + 1) objects, each of size S,
+ cannot exist due to size arithmetic overflow. S must be nonzero. */
+static inline bool
+re_x2alloc_oversized (size_t n, size_t s)
+{
+ return BE ((SIZE_MAX / s - 1) / 2 < n, 0);
+}
+
+/* Allocate an array of N objects, each with S bytes of memory,
+ dynamically, with error checking. S must be nonzero. */
+static inline void *
+re_xnmalloc (size_t n, size_t s)
+{
+ return re_alloc_oversized (n, s) ? NULL : malloc (n * s);
+}
+
+/* Change the size of an allocated block of memory P to an array of N
+ objects each of S bytes, with error checking. S must be nonzero. */
+static inline void *
+re_xnrealloc (void *p, size_t n, size_t s)
+{
+ return re_alloc_oversized (n, s) ? NULL : realloc (p, n * s);
+}
+
+/* Reallocate a block of memory P to an array of (2 * (*PN) + 1)
+ objects each of S bytes, with error checking. S must be nonzero.
+ If the allocation is successful, set *PN to the new allocation
+ count and return the resulting pointer. Otherwise, return
+ NULL. */
+static inline void *
+re_x2nrealloc (void *p, size_t *pn, size_t s)
+{
+ if (re_x2alloc_oversized (*pn, s))
+ return NULL;
+ else
+ {
+ /* Add 1 in case *PN is zero. */
+ size_t n1 = 2 * *pn + 1;
+ p = realloc (p, n1 * s);
+ if (BE (p != NULL, 1))
+ *pn = n1;
+ return p;
+ }
+}
+
struct bin_tree_t
{
struct bin_tree_t *parent;
if (regs == NULL)
nregs = 1;
else if (BE (bufp->re_regs_allocated == REG_FIXED
- && regs->rm_num_regs < bufp->re_nsub + 1, 0))
+ && regs->rm_num_regs <= bufp->re_nsub, 0))
{
nregs = regs->rm_num_regs;
if (BE (nregs < 1, 0))
}
else
nregs = bufp->re_nsub + 1;
- pmatch = re_malloc (regmatch_t, nregs);
+ pmatch = re_xmalloc (regmatch_t, nregs);
if (BE (pmatch == NULL, 0))
{
rval = -2;
/* Have the register data arrays been allocated? */
if (regs_allocated == REG_UNALLOCATED)
{ /* No. So allocate them with malloc. */
- regs->rm_start = re_malloc (regoff_t, need_regs);
+ regs->rm_start = re_xmalloc (regoff_t, need_regs);
regs->rm_end = re_malloc (regoff_t, need_regs);
if (BE (regs->rm_start == NULL, 0) || BE (regs->rm_end == NULL, 0))
return REG_UNALLOCATED;
if (BE (need_regs > regs->rm_num_regs, 0))
{
regoff_t *new_start =
- re_realloc (regs->rm_start, regoff_t, need_regs);
+ re_xrealloc (regs->rm_start, regoff_t, need_regs);
regoff_t *new_end = re_realloc (regs->rm_end, regoff_t, need_regs);
if (BE (new_start == NULL, 0) || BE (new_end == NULL, 0))
return REG_UNALLOCATED;
multi character collating element. */
if (nmatch > 1 || dfa->has_mb_node)
{
- mctx.state_log = re_malloc (re_dfastate_t *, mctx.input.bufs_len + 1);
+ mctx.state_log = re_xmalloc (re_dfastate_t *, mctx.input.bufs_len + 1);
if (BE (mctx.state_log == NULL, 0))
{
err = REG_ESPACE;
#endif
match_last = mctx->match_last;
halt_node = mctx->last_node;
- sifted_states = re_malloc (re_dfastate_t *, match_last + 1);
+ sifted_states = re_xmalloc (re_dfastate_t *, match_last + 1);
if (BE (sifted_states == NULL, 0))
{
ret = REG_ESPACE;
}
if (dfa->nbackref)
{
- lim_states = re_malloc (re_dfastate_t *, match_last + 1);
+ lim_states = re_xmalloc (re_dfastate_t *, match_last + 1);
if (BE (lim_states == NULL, 0))
{
ret = REG_ESPACE;
if (fs->num == fs->alloc)
{
struct re_fail_stack_ent_t *new_array =
- re_realloc (fs->stack, struct re_fail_stack_ent_t, fs->alloc * 2);
+ re_x2realloc (fs->stack, struct re_fail_stack_ent_t, &fs->alloc);
if (new_array == NULL)
return REG_ESPACE;
- fs->alloc *= 2;
fs->stack = new_array;
}
fs->stack[num].idx = str_idx;
fs->stack[num].node = dest_node;
- fs->stack[num].regs = re_malloc (regmatch_t, nregs);
+ fs->stack[num].regs = re_xmalloc (regmatch_t, nregs);
if (fs->stack[num].regs == NULL)
return REG_ESPACE;
memcpy (fs->stack[num].regs, regs, sizeof (regmatch_t) * nregs);
if (fl_backtrack)
{
fs = &fs_body;
- fs->stack = re_malloc (struct re_fail_stack_ent_t, fs->alloc);
+ fs->stack = re_xmalloc (struct re_fail_stack_ent_t, fs->alloc);
if (fs->stack == NULL)
return REG_ESPACE;
}
cur_node = dfa->init_node;
re_node_set_init_empty (&eps_via_nodes);
+ if (re_alloc_oversized (nmatch, sizeof (regmatch_t)))
+ {
+ free_fail_stack_return (fs);
+ return REG_ESPACE;
+ }
if (__libc_use_alloca (nmatch * sizeof (regmatch_t)))
prev_idx_match = (regmatch_t *) alloca (nmatch * sizeof (regmatch_t));
else
{
re_dfastate_t **new_array;
Idx old_alloc = path->alloc;
- path->alloc += last_str + mctx->max_mb_elem_len + 1;
- new_array = re_realloc (path->array, re_dfastate_t *, path->alloc);
- if (new_array == NULL)
- {
- path->alloc = old_alloc;
- return REG_ESPACE;
- }
+ Idx new_alloc = old_alloc + last_str + mctx->max_mb_elem_len + 1;
+ if (BE (new_alloc < old_alloc, 0))
+ return REG_ESPACE;
+ new_array = re_xrealloc (path->array, re_dfastate_t *, new_alloc);
+ if (BE (new_array == NULL, 0))
+ return REG_ESPACE;
path->array = new_array;
+ path->alloc = new_alloc;
memset (new_array + old_alloc, '\0',
- sizeof (re_dfastate_t *) * (path->alloc - old_alloc));
+ sizeof (re_dfastate_t *) * (new_alloc - old_alloc));
}
str_idx = path->next_idx == 0 ? top_str : path->next_idx;
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)) * SBC_MAX)
+ / (3 * sizeof (re_dfastate_t *)))
+ < ndests, 0))
+ goto out_free;
+
if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX
+ ndests * 3 * sizeof (re_dfastate_t *)))
dest_states = (re_dfastate_t **)
/* XXX We have no indication of the size of this buffer. If this
allocation fail we have no indication that the state_log array
does not have the right size. */
- re_dfastate_t **new_array = re_realloc (mctx->state_log, re_dfastate_t *,
- pstr->bufs_len + 1);
+ re_dfastate_t **new_array = re_xrealloc (mctx->state_log, re_dfastate_t *,
+ pstr->bufs_len + 1);
if (BE (new_array == NULL, 0))
return REG_ESPACE;
mctx->state_log = new_array;
mctx->match_last = REG_MISSING;
if (n > 0)
{
- mctx->bkref_ents = re_malloc (struct re_backref_cache_entry, n);
- mctx->sub_tops = re_malloc (re_sub_match_top_t *, n);
+ mctx->bkref_ents = re_xmalloc (struct re_backref_cache_entry, n);
+ mctx->sub_tops = re_xmalloc (re_sub_match_top_t *, n);
if (BE (mctx->bkref_ents == NULL || mctx->sub_tops == NULL, 0))
return REG_ESPACE;
}
if (mctx->nbkref_ents >= mctx->abkref_ents)
{
struct re_backref_cache_entry* new_entry;
- new_entry = re_realloc (mctx->bkref_ents, struct re_backref_cache_entry,
- mctx->abkref_ents * 2);
+ new_entry = re_x2realloc (mctx->bkref_ents, struct re_backref_cache_entry,
+ &mctx->abkref_ents);
if (BE (new_entry == NULL, 0))
{
re_free (mctx->bkref_ents);
}
mctx->bkref_ents = new_entry;
memset (mctx->bkref_ents + mctx->nbkref_ents, '\0',
- sizeof (struct re_backref_cache_entry) * mctx->abkref_ents);
- mctx->abkref_ents *= 2;
+ (sizeof (struct re_backref_cache_entry)
+ * (mctx->abkref_ents - mctx->nbkref_ents)));
}
if (mctx->nbkref_ents > 0
&& mctx->bkref_ents[mctx->nbkref_ents - 1].str_idx == str_idx)
#endif
if (BE (mctx->nsub_tops == mctx->asub_tops, 0))
{
- Idx new_asub_tops = mctx->asub_tops * 2;
- re_sub_match_top_t **new_array = re_realloc (mctx->sub_tops,
- re_sub_match_top_t *,
- new_asub_tops);
+ Idx new_asub_tops = mctx->asub_tops;
+ re_sub_match_top_t **new_array = re_x2realloc (mctx->sub_tops,
+ re_sub_match_top_t *,
+ &new_asub_tops);
if (BE (new_array == NULL, 0))
return REG_ESPACE;
mctx->sub_tops = new_array;
re_sub_match_last_t *new_entry;
if (BE (subtop->nlasts == subtop->alasts, 0))
{
- Idx new_alasts = 2 * subtop->alasts + 1;
- re_sub_match_last_t **new_array = re_realloc (subtop->lasts,
- re_sub_match_last_t *,
- new_alasts);
+ Idx new_alasts = subtop->alasts;
+ re_sub_match_last_t **new_array = re_x2realloc (subtop->lasts,
+ re_sub_match_last_t *,
+ &new_alasts);
if (BE (new_array == NULL, 0))
return NULL;
subtop->lasts = new_array;