Permalink
Browse files

Ensure we don't overflow fates buffer.

A recent Rakudo change used fates without having a fate array in the
first slot. This led to a buffer overflow, which showed up (at least
on Win32) as spectest failures. This fixes it not to overflow.
  • Loading branch information...
1 parent b94f739 commit ed35b15d9130bc97f6b223dc26043419107f2893 @jnthn jnthn committed Mar 15, 2013
Showing with 12 additions and 5 deletions.
  1. +12 −5 src/ops/nqp.ops
View
17 src/ops/nqp.ops
@@ -139,7 +139,7 @@ static INTVAL * nqp_nfa_run(PARROT_INTERP, NFABody *nfa, STRING *target, INTVAL
PMC *curst = nfa_curst;
PMC *nextst = nfa_nextst;
INTVAL *done, *fates;
- INTVAL i, num_states, total_fates, prev_fates;
+ INTVAL i, fate_arr_len, num_states, total_fates, prev_fates;
/* Allocate a "done states" array. */
num_states = nfa->num_states;
@@ -150,8 +150,8 @@ static INTVAL * nqp_nfa_run(PARROT_INTERP, NFABody *nfa, STRING *target, INTVAL
VTABLE_set_integer_native(interp, nextst, 0);
/* Allocate fates array. */
- fates = (INTVAL *)mem_sys_allocate(
- sizeof(INTVAL) * (1 + VTABLE_elements(interp, nfa->fates)));
+ fate_arr_len = 1 + VTABLE_elements(interp, nfa->fates);
+ fates = (INTVAL *)mem_sys_allocate(sizeof(INTVAL) * fate_arr_len);
total_fates = 0;
VTABLE_push_integer(interp, nextst, 1);
@@ -200,10 +200,17 @@ static INTVAL * nqp_nfa_run(PARROT_INTERP, NFABody *nfa, STRING *target, INTVAL
prev_fates--;
}
}
- if (found_fate)
+ if (found_fate) {
fates[total_fates - 1] = arg;
- else
+ }
+ else {
+ if (total_fates >= fate_arr_len) {
+ fate_arr_len = total_fates + 1;
+ fates = (INTVAL *)mem_sys_realloc(fates,
+ sizeof(INTVAL) * fate_arr_len);
+ }
fates[total_fates++] = arg;
+ }
}
else if (act == EDGE_EPSILON && to <= num_states && done[to] != gen) {
VTABLE_push_integer(interp, curst, to);

0 comments on commit ed35b15

Please sign in to comment.