summaryrefslogtreecommitdiffstats
path: root/modules/libjar/nsZipArchive.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/libjar/nsZipArchive.cpp')
-rw-r--r--modules/libjar/nsZipArchive.cpp38
1 files changed, 36 insertions, 2 deletions
diff --git a/modules/libjar/nsZipArchive.cpp b/modules/libjar/nsZipArchive.cpp
index 2f12af5f0..b28fddc18 100644
--- a/modules/libjar/nsZipArchive.cpp
+++ b/modules/libjar/nsZipArchive.cpp
@@ -4,7 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
- * This module implements a simple archive extractor for the PKZIP format.
+ * This module implements a simple archive extractor.
*
* The underlying nsZipArchive is NOT thread-safe. Do not pass references
* or pointers to it across thread boundaries.
@@ -17,6 +17,7 @@
#define READTYPE int32_t
#include "zlib.h"
+#include "brotli/decode.h"
#include "nsISupportsUtils.h"
#include "prio.h"
#include "plstr.h"
@@ -1186,6 +1187,7 @@ nsZipCursor::nsZipCursor(nsZipItem *item, nsZipArchive *aZip, uint8_t* aBuf,
: mItem(item)
, mBuf(aBuf)
, mBufSize(aBufSize)
+ , mBrotliState(nullptr)
, mCRC(0)
, mDoCRC(doCRC)
{
@@ -1200,6 +1202,10 @@ nsZipCursor::nsZipCursor(nsZipItem *item, nsZipArchive *aZip, uint8_t* aBuf,
mZs.avail_in = item->Size();
mZs.next_in = (Bytef*)aZip->GetData(item);
+
+ if (mItem->Compression() == MOZ_JAR_BROTLI) {
+ mBrotliState = BrotliDecoderCreateInstance(nullptr, nullptr, nullptr);
+ }
if (doCRC)
mCRC = crc32(0L, Z_NULL, 0);
@@ -1210,6 +1216,9 @@ nsZipCursor::~nsZipCursor()
if (mItem->Compression() == DEFLATED) {
inflateEnd(&mZs);
}
+ if (mItem->Compression() == MOZ_JAR_BROTLI) {
+ BrotliDecoderDestroyInstance(mBrotliState);
+ }
}
uint8_t* nsZipCursor::ReadOrCopy(uint32_t *aBytesRead, bool aCopy) {
@@ -1246,6 +1255,29 @@ MOZ_WIN_MEM_TRY_BEGIN
*aBytesRead = mZs.next_out - buf;
verifyCRC = (zerr == Z_STREAM_END);
break;
+ case MOZ_JAR_BROTLI: {
+ buf = mBuf;
+ mZs.next_out = buf;
+ /* The brotli library wants size_t, but z_stream only contains
+ * unsigned int for avail_*. So use temporary stack values. */
+ size_t avail_out = mBufSize;
+ size_t avail_in = mZs.avail_in;
+ BrotliDecoderResult result = BrotliDecoderDecompressStream(
+ mBrotliState,
+ &avail_in, const_cast<const unsigned char**>(&mZs.next_in),
+ &avail_out, &mZs.next_out, nullptr);
+ /* We don't need to update avail_out, it's not used outside this
+ * function. */
+ mZs.avail_in = avail_in;
+
+ if (result == BROTLI_DECODER_RESULT_ERROR) {
+ return nullptr;
+ }
+
+ *aBytesRead = mZs.next_out - buf;
+ verifyCRC = (result == BROTLI_DECODER_RESULT_SUCCESS);
+ break;
+ }
default:
return nullptr;
}
@@ -1272,7 +1304,9 @@ nsZipItemPtr_base::nsZipItemPtr_base(nsZipArchive *aZip,
return;
uint32_t size = 0;
- if (item->Compression() == DEFLATED) {
+ bool compressed = (item->Compression() == DEFLATED) ||
+ (item->Compression() == MOZ_JAR_BROTLI);
+ if (compressed) {
size = item->RealSize();
mAutoBuf = MakeUniqueFallible<uint8_t[]>(size);
if (!mAutoBuf) {