diff options
Diffstat (limited to 'modules/libjar/nsZipArchive.cpp')
-rw-r--r-- | modules/libjar/nsZipArchive.cpp | 38 |
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) { |