Skip to content

Commit

Permalink
Fix fa_ambig_example() when the automata involve NULs
Browse files Browse the repository at this point in the history
After the example for `amb' was calculated, the code that generated the
*UPV string and pointers *PV and *V within this string used strlen() to
calculate the length of the example; however, the example string may
contain NUL bytes. Thus, it could happen that not enough space would be
allocated for the *UPV string.

Instead of computing the length of the example using strlen(), just use
`s_len'.

Added a new test to fatest, testAmbigWithNuls.
  • Loading branch information
dtrebbien committed Nov 25, 2015
1 parent 155746c commit 8a292c1
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 5 deletions.
18 changes: 13 additions & 5 deletions src/fa.c
Original file line number Diff line number Diff line change
Expand Up @@ -2890,6 +2890,7 @@ int fa_ambig_example(struct fa *fa1, struct fa *fa2,
static const char X = '\001';
static const char Y = '\002';
char *result = NULL, *s = NULL;
size_t result_len = 0;
int ret = -1, r;
struct fa *mp = NULL, *ms = NULL, *sp = NULL, *ss = NULL, *amb = NULL;
struct fa *a1f = NULL, *a1t = NULL, *a2f = NULL, *a2t = NULL;
Expand Down Expand Up @@ -2973,23 +2974,30 @@ int fa_ambig_example(struct fa *fa1, struct fa *fa2,

if (s != NULL) {
char *t;
F(ALLOC_N(result, (strlen(s)-1)/2 + 1));
result_len = (s_len-1)/2 - 1;
F(ALLOC_N(result, result_len + 1));
t = result;
int i = 0;
for (i=0; s[2*i] == X; i++)
for (i=0; s[2*i] == X; i++) {
assert((t - result) < result_len);
*t++ = s[2*i + 1];
}
if (pv != NULL)
*pv = t;
i += 1;

for ( ;s[2*i] == X; i++)
for ( ;s[2*i] == X; i++) {
assert((t - result) < result_len);
*t++ = s[2*i + 1];
}
if (v != NULL)
*v = t;
i += 1;

for (; 2*i+1 < strlen(s); i++)
for (; 2*i+1 < s_len; i++) {
assert((t - result) < result_len);
*t++ = s[2*i + 1];
}
}
ret = 0;

Expand All @@ -3010,7 +3018,7 @@ int fa_ambig_example(struct fa *fa1, struct fa *fa2,
FREE(s);
*upv = result;
if (result != NULL)
*upv_len = strlen(result);
*upv_len = result_len;
return ret;
error:
FREE(result);
Expand Down
27 changes: 27 additions & 0 deletions tests/fatest.c
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ static void assertAmbig(CuTest *tc, const char *regexp1, const char *regexp2,
CuAssertPtrNotNull(tc, v);

CuAssertStrEquals(tc, exp_upv, upv);
CuAssertIntEquals(tc, strlen(exp_upv), upv_len);
CuAssertStrEquals(tc, exp_pv, pv);
CuAssertStrEquals(tc, exp_v, v);
free(upv);
Expand Down Expand Up @@ -423,6 +424,31 @@ static void testAmbig(CuTest *tc) {
assertNotAmbig(tc, "(a|b|c|d|abcd)", "(a|b|c|d|abcd)");
}

static void testAmbigWithNuls(CuTest *tc) {
struct fa *fa1 = make_fa(tc, "X\0ba?", 5, REG_NOERROR);
struct fa *fa2 = make_fa(tc, "a?\0Y", 4, REG_NOERROR);
char *upv, *pv, *v;
size_t upv_len;
int r = fa_ambig_example(fa1, fa2, &upv, &upv_len, &pv, &v);
CuAssertIntEquals(tc, 0, r);
CuAssertIntEquals(tc, 6, (int)upv_len);
/* u = "X\0b" */
size_t u_len = pv - upv;
CuAssertIntEquals(tc, 3, u_len);
CuAssertIntEquals(tc, (int)'X', upv[0]);
CuAssertIntEquals(tc, (int)'\0', upv[1]);
CuAssertIntEquals(tc, (int)'b', upv[2]);
/* p = "a" */
size_t p_len = v - pv;
CuAssertIntEquals(tc, 1, p_len);
CuAssertIntEquals(tc, (int)'a', pv[0]);
/* v = "\0Y" */
size_t v_len = upv_len - (v - upv);
CuAssertIntEquals(tc, 2, v_len);
CuAssertIntEquals(tc, (int)'\0', v[0]);
CuAssertIntEquals(tc, (int)'Y', v[1]);
}

static void assertFaAsRegexp(CuTest *tc, const char *regexp) {
char *re;
size_t re_len;
Expand Down Expand Up @@ -657,6 +683,7 @@ int main(int argc, char **argv) {
SUITE_ADD_TEST(suite, testOverlap);
SUITE_ADD_TEST(suite, testExample);
SUITE_ADD_TEST(suite, testAmbig);
SUITE_ADD_TEST(suite, testAmbigWithNuls);
SUITE_ADD_TEST(suite, testAsRegexp);
SUITE_ADD_TEST(suite, testAsRegexpMinus);
SUITE_ADD_TEST(suite, testRangeEnd);
Expand Down

0 comments on commit 8a292c1

Please sign in to comment.