Bug 1238558 (part 1) - Add Decoder::BeforeFinishInternal(). r=tnikkel.

This commit is contained in:
Nicholas Nethercote 2016-01-27 16:15:06 -08:00
parent ef4157031e
commit 506abe122b
4 changed files with 27 additions and 10 deletions

View File

@ -190,6 +190,7 @@ void
Decoder::CompleteDecode() Decoder::CompleteDecode()
{ {
// Implementation-specific finalization // Implementation-specific finalization
BeforeFinishInternal();
if (!HasError()) { if (!HasError()) {
FinishInternal(); FinishInternal();
} else { } else {
@ -393,6 +394,7 @@ Decoder::AllocateFrameInternal(uint32_t aFrameNum,
*/ */
void Decoder::InitInternal() { } void Decoder::InitInternal() { }
void Decoder::BeforeFinishInternal() { }
void Decoder::FinishInternal() { } void Decoder::FinishInternal() { }
void Decoder::FinishWithErrorInternal() { } void Decoder::FinishWithErrorInternal() { }

View File

@ -283,9 +283,14 @@ protected:
/* /*
* Internal hooks. Decoder implementations may override these and * Internal hooks. Decoder implementations may override these and
* only these methods. * only these methods.
*
* BeforeFinishInternal() can be used to detect if decoding is in an
* incomplete state, e.g. due to file truncation, in which case it should
* call PostDataError().
*/ */
virtual void InitInternal(); virtual void InitInternal();
virtual void WriteInternal(const char* aBuffer, uint32_t aCount) = 0; virtual void WriteInternal(const char* aBuffer, uint32_t aCount) = 0;
virtual void BeforeFinishInternal();
virtual void FinishInternal(); virtual void FinishInternal();
virtual void FinishWithErrorInternal(); virtual void FinishWithErrorInternal();

View File

@ -220,6 +220,14 @@ nsBMPDecoder::GetCompressedImageSize() const
: mH.mImageSize; : mH.mImageSize;
} }
void
nsBMPDecoder::BeforeFinishInternal()
{
if (!IsMetadataDecode() && !mImageData) {
PostDataError();
}
}
void void
nsBMPDecoder::FinishInternal() nsBMPDecoder::FinishInternal()
{ {
@ -232,17 +240,18 @@ nsBMPDecoder::FinishInternal()
// Send notifications if appropriate. // Send notifications if appropriate.
if (!IsMetadataDecode() && HasSize()) { if (!IsMetadataDecode() && HasSize()) {
// We should have image data.
MOZ_ASSERT(mImageData);
// If it was truncated, fill in the missing pixels as black. // If it was truncated, fill in the missing pixels as black.
if (mImageData) { while (mCurrentRow > 0) {
while (mCurrentRow > 0) { uint32_t* dst = RowBuffer();
uint32_t* dst = RowBuffer(); while (mCurrentPos < mH.mWidth) {
while (mCurrentPos < mH.mWidth) { SetPixel(dst, 0, 0, 0);
SetPixel(dst, 0, 0, 0); mCurrentPos++;
mCurrentPos++;
}
mCurrentPos = 0;
FinishRow();
} }
mCurrentPos = 0;
FinishRow();
} }
// Invalidate. // Invalidate.
@ -492,7 +501,7 @@ nsBMPDecoder::ReadInfoHeaderSize(const char* aData, size_t aLength)
PostDataError(); PostDataError();
return Transition::TerminateFailure(); return Transition::TerminateFailure();
} }
// ICO BMPs must have a WinVMPv3 header. nsICODecoder should have already // ICO BMPs must have a WinBMPv3 header. nsICODecoder should have already
// terminated decoding if this isn't the case. // terminated decoding if this isn't the case.
MOZ_ASSERT_IF(mIsWithinICO, mH.mBIHSize == InfoHeaderLength::WIN_V3); MOZ_ASSERT_IF(mIsWithinICO, mH.mBIHSize == InfoHeaderLength::WIN_V3);

View File

@ -151,6 +151,7 @@ public:
virtual void WriteInternal(const char* aBuffer, virtual void WriteInternal(const char* aBuffer,
uint32_t aCount) override; uint32_t aCount) override;
virtual void BeforeFinishInternal() override;
virtual void FinishInternal() override; virtual void FinishInternal() override;
private: private: