mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 07:13:20 +00:00
Bug 1781094 - Revert the some changes done in bug 1759745 and also try to take more output data, r=necko-reviewers,dragana
The problem in the previous change is that `mBrotli->mTotalOut` is not updated immediately. In the case that `nsUnknownDecoder` is involved in the listener chain and the result of `Brotli` decoder is `BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT`, `mBrotli->mTotalOut` is 0. In the end, when `nsHTTPCompressConv::OnStopRequest` is called by `nsUnknownDecoder` [1], an error code is set [2]. The safest way would be to revert the changes done in bug 1759745. However, to make the case in bug 1759745 work ( and also make `test_brotli_decoding.js` pass), we need to add another while loop and try to get more output data from the decoder. [1] https://searchfox.org/mozilla-central/rev/d5edb4a4538657b7d691a41c00e6796a19ade6e7/netwerk/streamconv/converters/nsUnknownDecoder.cpp#778 [2] https://searchfox.org/mozilla-central/rev/d5edb4a4538657b7d691a41c00e6796a19ade6e7/netwerk/streamconv/converters/nsHTTPCompressConv.cpp#167 Differential Revision: https://phabricator.services.mozilla.com/D152729
This commit is contained in:
parent
d690c61a8f
commit
5c8ac9f08f
@ -201,9 +201,14 @@ nsresult nsHTTPCompressConv::BrotliHandler(nsIInputStream* stream,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
auto outBuffer = MakeUniqueFallible<uint8_t[]>(kOutSize);
|
||||
if (outBuffer == nullptr) {
|
||||
self->mBrotli->mStatus = NS_ERROR_OUT_OF_MEMORY;
|
||||
return self->mBrotli->mStatus;
|
||||
}
|
||||
do {
|
||||
outSize = 0;
|
||||
outPtr = nullptr;
|
||||
outSize = kOutSize;
|
||||
outPtr = outBuffer.get();
|
||||
|
||||
// brotli api is documented in brotli/dec/decode.h and brotli/dec/decode.c
|
||||
LOG(("nsHttpCompresssConv %p brotlihandler decompress %zu\n", self, avail));
|
||||
@ -212,11 +217,13 @@ nsresult nsHTTPCompressConv::BrotliHandler(nsIInputStream* stream,
|
||||
&self->mBrotli->mState, &avail,
|
||||
reinterpret_cast<const unsigned char**>(&dataIn), &outSize, &outPtr,
|
||||
&totalOut);
|
||||
outSize = kOutSize - outSize;
|
||||
self->mBrotli->mTotalOut = totalOut;
|
||||
self->mBrotli->mBrotliStateIsStreamEnd =
|
||||
BrotliDecoderIsFinished(&self->mBrotli->mState);
|
||||
LOG(("nsHttpCompresssConv %p brotlihandler decompress rv=%" PRIx32, self,
|
||||
static_cast<uint32_t>(res)));
|
||||
LOG(("nsHttpCompresssConv %p brotlihandler decompress rv=%" PRIx32
|
||||
" out=%zu\n",
|
||||
self, static_cast<uint32_t>(res), outSize));
|
||||
|
||||
if (res == BROTLI_DECODER_RESULT_ERROR) {
|
||||
LOG(("nsHttpCompressConv %p marking invalid encoding", self));
|
||||
@ -235,17 +242,35 @@ nsresult nsHTTPCompressConv::BrotliHandler(nsIInputStream* stream,
|
||||
}
|
||||
}
|
||||
|
||||
while (::BrotliDecoderHasMoreOutput(&self->mBrotli->mState)) {
|
||||
outSize = kOutSize;
|
||||
const uint8_t* buffer =
|
||||
::BrotliDecoderTakeOutput(&self->mBrotli->mState, &outSize);
|
||||
nsresult rv = self->do_OnDataAvailable(
|
||||
self->mBrotli->mRequest, self->mBrotli->mSourceOffset,
|
||||
reinterpret_cast<const char*>(buffer), outSize);
|
||||
auto callOnDataAvailable = [&](uint64_t aSourceOffset, const char* aBuffer,
|
||||
uint32_t aCount) {
|
||||
nsresult rv = self->do_OnDataAvailable(self->mBrotli->mRequest,
|
||||
aSourceOffset, aBuffer, aCount);
|
||||
LOG(("nsHttpCompressConv %p BrotliHandler ODA rv=%" PRIx32, self,
|
||||
static_cast<uint32_t>(rv)));
|
||||
if (NS_FAILED(rv)) {
|
||||
self->mBrotli->mStatus = rv;
|
||||
}
|
||||
|
||||
return rv;
|
||||
};
|
||||
|
||||
if (outSize > 0) {
|
||||
if (NS_FAILED(callOnDataAvailable(
|
||||
self->mBrotli->mSourceOffset,
|
||||
reinterpret_cast<const char*>(outBuffer.get()), outSize))) {
|
||||
return self->mBrotli->mStatus;
|
||||
}
|
||||
}
|
||||
|
||||
// See bug 1759745. If the decoder has more output data, take it.
|
||||
while (::BrotliDecoderHasMoreOutput(&self->mBrotli->mState)) {
|
||||
outSize = kOutSize;
|
||||
const uint8_t* buffer =
|
||||
::BrotliDecoderTakeOutput(&self->mBrotli->mState, &outSize);
|
||||
if (NS_FAILED(callOnDataAvailable(self->mBrotli->mSourceOffset,
|
||||
reinterpret_cast<const char*>(buffer),
|
||||
outSize))) {
|
||||
return self->mBrotli->mStatus;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user