summaryrefslogtreecommitdiff
path: root/src/VBox/Runtime/common/zip/zip.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Runtime/common/zip/zip.cpp')
-rw-r--r--src/VBox/Runtime/common/zip/zip.cpp45
1 files changed, 43 insertions, 2 deletions
diff --git a/src/VBox/Runtime/common/zip/zip.cpp b/src/VBox/Runtime/common/zip/zip.cpp
index 8abc2602..fa8d140f 100644
--- a/src/VBox/Runtime/common/zip/zip.cpp
+++ b/src/VBox/Runtime/common/zip/zip.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -574,7 +574,8 @@ static DECLCALLBACK(int) rtZipZlibCompInit(PRTZIPCOMP pZip, RTZIPLEVEL enmLevel)
static DECLCALLBACK(int) rtZipZlibDecompress(PRTZIPDECOMP pZip, void *pvBuf, size_t cbBuf, size_t *pcbWritten)
{
pZip->u.Zlib.next_out = (Bytef *)pvBuf;
- pZip->u.Zlib.avail_out = (uInt)cbBuf; Assert(pZip->u.Zlib.avail_out == cbBuf);
+ pZip->u.Zlib.avail_out = (uInt)cbBuf;
+ Assert(pZip->u.Zlib.avail_out == cbBuf);
/*
* Be greedy reading input, even if no output buffer is left. It's possible
@@ -1915,6 +1916,46 @@ RTDECL(int) RTZipBlockDecompress(RTZIPTYPE enmType, uint32_t fFlags,
}
case RTZIPTYPE_ZLIB:
+ {
+#ifdef RTZIP_USE_ZLIB
+ AssertReturn(cbSrc == (uInt)cbSrc, VERR_TOO_MUCH_DATA);
+ AssertReturn(cbDst == (uInt)cbDst, VERR_OUT_OF_RANGE);
+
+ z_stream ZStrm;
+ RT_ZERO(ZStrm);
+ ZStrm.next_in = (Bytef *)pvSrc;
+ ZStrm.avail_in = (uInt)cbSrc;
+ ZStrm.next_out = (Bytef *)pvDst;
+ ZStrm.avail_out = (uInt)cbDst;
+
+ int rc = inflateInit(&ZStrm);
+ if (RT_UNLIKELY(rc != Z_OK))
+ return zipErrConvertFromZlib(rc, false /*fCompressing*/);
+ rc = inflate(&ZStrm, Z_FINISH);
+ if (rc != Z_STREAM_END)
+ {
+ inflateEnd(&ZStrm);
+ if ((rc == Z_BUF_ERROR && ZStrm.avail_in == 0) || rc == Z_NEED_DICT)
+ return VERR_ZIP_CORRUPTED;
+ if (rc == Z_BUF_ERROR)
+ return VERR_BUFFER_OVERFLOW;
+ AssertReturn(rc < Z_OK, VERR_GENERAL_FAILURE);
+ return zipErrConvertFromZlib(rc, false /*fCompressing*/);
+ }
+ rc = inflateEnd(&ZStrm);
+ if (rc != Z_OK)
+ return zipErrConvertFromZlib(rc, false /*fCompressing*/);
+
+ if (pcbSrcActual)
+ *pcbSrcActual = ZStrm.avail_in - cbSrc;
+ if (pcbDstActual)
+ *pcbDstActual = ZStrm.total_out;
+ break;
+#else
+ return VERR_NOT_SUPPORTED;
+#endif
+ }
+
case RTZIPTYPE_BZLIB:
return VERR_NOT_SUPPORTED;