From 0278c307762fba87e2e0ab36a7bcb489554d78c2 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 24 Feb 2016 11:15:00 -0500 Subject: [PATCH] zip: Don't allocate a 256k buffer on the stack for zip64 parsing. --- src/archiver_zip.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/archiver_zip.c b/src/archiver_zip.c index f93cf408..11534f69 100644 --- a/src/archiver_zip.c +++ b/src/archiver_zip.c @@ -1176,25 +1176,34 @@ static PHYSFS_sint64 zip64_find_end_of_central_dir(PHYSFS_Io *io, /* Just try moving back at most 256k. Oh well. */ if ((offset < pos) && (pos > 4)) { - /* we assume you can eat this stack if you handle Zip64 files. */ - PHYSFS_uint8 buf[256 * 1024]; + const PHYSFS_uint64 maxbuflen = 256 * 1024; PHYSFS_uint64 len = pos - offset; + PHYSFS_uint8 *buf = NULL; PHYSFS_sint32 i; - if (len > sizeof (buf)) - len = sizeof (buf); + if (len > maxbuflen) + len = maxbuflen; + + buf = (PHYSFS_uint8 *) __PHYSFS_smallAlloc(len); + BAIL_IF_MACRO(!buf, PHYSFS_ERR_OUT_OF_MEMORY, -1); + + if (!io->seek(io, pos - len) || !__PHYSFS_readAll(io, buf, len)) + { + __PHYSFS_smallFree(buf); + return -1; /* error was set elsewhere. */ + } /* if */ - BAIL_IF_MACRO(!io->seek(io, pos - len), ERRPASS, -1); - BAIL_IF_MACRO(!__PHYSFS_readAll(io, buf, len), ERRPASS, -1); for (i = (PHYSFS_sint32) (len - 4); i >= 0; i--) { - if (buf[i] != 0x50) - continue; - if ( (buf[i+1] == 0x4b) && - (buf[i+2] == 0x06) && - (buf[i+3] == 0x06) ) + if ( (buf[i] == 0x50) && (buf[i+1] == 0x4b) && + (buf[i+2] == 0x06) && (buf[i+3] == 0x06) ) + { + __PHYSFS_smallFree(buf); return pos - (len - i); + } /* if */ } /* for */ + + __PHYSFS_smallFree(buf); } /* if */ BAIL_MACRO(PHYSFS_ERR_CORRUPT, -1); /* didn't find it. */