Untar failure path fixes

By xDraconian, ensure we call inflateEnd in failure cases, otherwise
the inflate context is leaked.
This commit is contained in:
James Turner
2017-12-11 18:14:40 +00:00
parent 68053d64b5
commit f6ded69fa3
2 changed files with 8 additions and 2 deletions
+4 -2
View File
@@ -33,6 +33,7 @@ void testTarGz()
SG_VERIFY(TarExtractor::isTarData(buf, bufSize)); SG_VERIFY(TarExtractor::isTarData(buf, bufSize));
f.close();
} }
void testPlainTar() void testPlainTar()
@@ -48,12 +49,13 @@ void testPlainTar()
SG_VERIFY(TarExtractor::isTarData(buf, bufSize)); SG_VERIFY(TarExtractor::isTarData(buf, bufSize));
f.close();
} }
int main (int ac, char ** av) int main(int ac, char ** av)
{ {
testTarGz(); testTarGz();
testPlainTar(); testPlainTar();
return 0; return 0;
} }
+4
View File
@@ -403,22 +403,26 @@ bool TarExtractor::isTarData(const uint8_t* bytes, size_t count)
z.avail_in = count; z.avail_in = count;
if (inflateInit2(&z, ZLIB_INFLATE_WINDOW_BITS | ZLIB_DECODE_GZIP_HEADER) != Z_OK) { if (inflateInit2(&z, ZLIB_INFLATE_WINDOW_BITS | ZLIB_DECODE_GZIP_HEADER) != Z_OK) {
inflateEnd(&z);
return false; return false;
} }
int result = inflate(&z, Z_SYNC_FLUSH); int result = inflate(&z, Z_SYNC_FLUSH);
if (result != Z_OK) { if (result != Z_OK) {
SG_LOG(SG_IO, SG_WARN, "inflate failed:" << result); SG_LOG(SG_IO, SG_WARN, "inflate failed:" << result);
inflateEnd(&z);
return false; // not tar data return false; // not tar data
} }
size_t written = 4096 - z.avail_out; size_t written = 4096 - z.avail_out;
if (written < TAR_HEADER_BLOCK_SIZE) { if (written < TAR_HEADER_BLOCK_SIZE) {
SG_LOG(SG_IO, SG_WARN, "insufficient data for header"); SG_LOG(SG_IO, SG_WARN, "insufficient data for header");
inflateEnd(&z);
return false; return false;
} }
header = reinterpret_cast<UstarHeaderBlock*>(zlibOutput); header = reinterpret_cast<UstarHeaderBlock*>(zlibOutput);
inflateEnd(&z);
} else { } else {
// uncompressed tar // uncompressed tar
if (count < TAR_HEADER_BLOCK_SIZE) { if (count < TAR_HEADER_BLOCK_SIZE) {