aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--regcomp.c7
-rw-r--r--regex_internal.h30
-rw-r--r--regexec.c16
4 files changed, 53 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 0cb4feec..98a4f7ce 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2015-04-13 Arnold D. Robbins <arnold@skeeve.com>
+
+ * regcomp.c (analyze): Prevent malloc(0).
+ * regex_internal.h (test_malloc, test_realloc): New functions
+ that check for zero count.
+ (re_malloc, re_realloc): Adjust to call the new functions for gawk.
+ * regexec.c (buid_trtable, match_ctx_clean): Replace malloc/free
+ with re_malloc/re_free.
+
2015-04-12 Arnold D. Robbins <arnold@skeeve.com>
* Makefile.am (efence): Make this link again.
diff --git a/regcomp.c b/regcomp.c
index a3148c0e..f3dcb3ea 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -1217,7 +1217,12 @@ analyze (regex_t *preg)
|| dfa->eclosures == NULL, 0))
return REG_ESPACE;
- dfa->subexp_map = re_malloc (int, preg->re_nsub);
+ /* some malloc()-checkers don't like zero allocations */
+ if (preg->re_nsub > 0)
+ dfa->subexp_map = re_malloc (int, preg->re_nsub);
+ else
+ dfa->subexp_map = NULL;
+
if (dfa->subexp_map != NULL)
{
int i;
diff --git a/regex_internal.h b/regex_internal.h
index 9aab5e52..6a870f23 100644
--- a/regex_internal.h
+++ b/regex_internal.h
@@ -467,8 +467,38 @@ static unsigned int re_string_context_at (const re_string_t *input, int idx,
# endif
#endif
+/*
+ * GAWK checks for zero-size allocations everywhere else,
+ * do it here too.
+ */
+#ifndef GAWK
#define re_malloc(t,n) ((t *) malloc ((n) * sizeof (t)))
#define re_realloc(p,t,n) ((t *) realloc (p, (n) * sizeof (t)))
+#else
+static void *
+test_malloc(size_t count, const char *file, size_t line)
+{
+ if (count == 0) {
+ fprintf(stderr, "%s:%d: allocation of zero bytes\n",
+ file, line);
+ exit(1);
+ }
+ return malloc(count);
+}
+
+static void *
+test_realloc(void *p, size_t count, const char *file, size_t line)
+{
+ if (count == 0) {
+ fprintf(stderr, "%s:%d: reallocation of zero bytes\n",
+ file, line);
+ exit(1);
+ }
+ return realloc(p, count);
+}
+#define re_malloc(t,n) ((t *) test_malloc (((n) * sizeof (t)), __FILE__, __LINE__))
+#define re_realloc(p,t,n) ((t *) test_realloc (p, (n) * sizeof (t), __FILE__, __LINE__))
+#endif
#define re_free(p) free (p)
struct bin_tree_t
diff --git a/regexec.c b/regexec.c
index 30f2ec74..46a4d0ae 100644
--- a/regexec.c
+++ b/regexec.c
@@ -3381,7 +3381,7 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
if (BE (ndests <= 0, 0))
{
if (dests_node_malloced)
- free (dests_alloc);
+ re_free (dests_alloc);
/* Return 0 in case of an error, 1 otherwise. */
if (ndests == 0)
{
@@ -3413,18 +3413,18 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
else
#endif
{
- dest_states = (re_dfastate_t **)
- malloc (ndests * 3 * sizeof (re_dfastate_t *));
+ dest_states =
+ re_malloc (re_dfastate_t *, ndests * 3);
if (BE (dest_states == NULL, 0))
{
out_free:
if (dest_states_malloced)
- free (dest_states);
+ re_free (dest_states);
re_node_set_free (&follows);
for (i = 0; i < ndests; ++i)
re_node_set_free (dests_node + i);
if (dests_node_malloced)
- free (dests_alloc);
+ re_free (dests_alloc);
return 0;
}
dest_states_malloced = true;
@@ -3555,14 +3555,14 @@ out_free:
}
if (dest_states_malloced)
- free (dest_states);
+ re_free (dest_states);
re_node_set_free (&follows);
for (i = 0; i < ndests; ++i)
re_node_set_free (dests_node + i);
if (dests_node_malloced)
- free (dests_alloc);
+ re_free (dests_alloc);
return 1;
}
@@ -4225,7 +4225,7 @@ match_ctx_clean (re_match_context_t *mctx)
re_free (top->path->array);
re_free (top->path);
}
- free (top);
+ re_free (top);
}
mctx->nsub_tops = 0;