summaryrefslogtreecommitdiff
path: root/lib/fnmatch_loop.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2003-10-16 06:51:24 +0000
committerPaul Eggert <eggert@cs.ucla.edu>2003-10-16 06:51:24 +0000
commitb01279bf4c3b8ca5e26e2d2e1512a101a7f1dc7c (patch)
tree66467b6f69a6f4990501122798b2da7893f5a7f8 /lib/fnmatch_loop.c
parent6942bbb52b3b0cdbdedcdf8b4356387631a2e8f3 (diff)
downloadgnulib-b01279bf4c3b8ca5e26e2d2e1512a101a7f1dc7c.tar.gz
Check for address arithmetic overflow.
Do not alloca huge buffers.
Diffstat (limited to 'lib/fnmatch_loop.c')
-rw-r--r--lib/fnmatch_loop.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/lib/fnmatch_loop.c b/lib/fnmatch_loop.c
index a83dd96169..1a1e9cfb2f 100644
--- a/lib/fnmatch_loop.c
+++ b/lib/fnmatch_loop.c
@@ -1042,16 +1042,23 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,
if (level-- == 0)
{
/* This means we found the end of the pattern. */
+#define ALLOCA_LIMIT 8000
#define NEW_PATTERN \
struct patternlist *newp; \
size_t plen; \
+ size_t plensize; \
+ size_t newpsize; \
\
plen = (opt == L('?') || opt == L('@') \
? pattern_len \
: p - startp + 1); \
- newp = (struct patternlist *) \
- alloca (offsetof (struct patternlist, str) \
- + (plen * sizeof (CHAR))); \
+ plensize = plen * sizeof (CHAR); \
+ newpsize = offsetof (struct patternlist, str) + plensize; \
+ if ((size_t) -1 / sizeof (CHAR) < plen \
+ || newpsize < offsetof (struct patternlist, str) \
+ || ALLOCA_LIMIT <= newpsize) \
+ return -1; \
+ newp = (struct patternlist *) alloca (newpsize); \
*((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L('\0'); \
newp->next = NULL; \
*lastp = newp; \