From eed6421dc45a5cc74986b2ef0870974c829f829e Mon Sep 17 00:00:00 2001 From: Dan Sinclair Date: Tue, 28 Mar 2017 12:44:58 -0400 Subject: Add bounds check into JBIG2 Arith decoder. Currently when the BitStream runs out of bits it pretends that it still has content and will continue to return the last byte over and over again. This Cl updates the jbig decoder to detect that the bit stream is complete and returns a decode error. Bug: chromium:665056 Change-Id: I61ca75713e677a2c280e80374b8dcfd48bee67d8 Reviewed-on: https://pdfium-review.googlesource.com/3244 Commit-Queue: dsinclair Reviewed-by: Tom Sepez --- core/fxcodec/jbig2/JBig2_ArithDecoder.cpp | 5 +- core/fxcodec/jbig2/JBig2_ArithDecoder.h | 7 +- core/fxcodec/jbig2/JBig2_BitStream.cpp | 18 +-- core/fxcodec/jbig2/JBig2_BitStream.h | 3 +- core/fxcodec/jbig2/JBig2_GrdProc.cpp | 219 +++++++++++++++++++++++++++--- 5 files changed, 224 insertions(+), 28 deletions(-) diff --git a/core/fxcodec/jbig2/JBig2_ArithDecoder.cpp b/core/fxcodec/jbig2/JBig2_ArithDecoder.cpp index 0d45f57bdf..78c7939458 100644 --- a/core/fxcodec/jbig2/JBig2_ArithDecoder.cpp +++ b/core/fxcodec/jbig2/JBig2_ArithDecoder.cpp @@ -56,7 +56,7 @@ int DecodeNLPS(JBig2ArithCtx* pCX, const JBig2ArithQe& qe) { } // namespace CJBig2_ArithDecoder::CJBig2_ArithDecoder(CJBig2_BitStream* pStream) - : m_pStream(pStream) { + : m_Complete(false), m_pStream(pStream) { m_B = m_pStream->getCurByte_arith(); m_C = (m_B ^ 0xff) << 16; BYTEIN(); @@ -107,6 +107,9 @@ void CJBig2_ArithDecoder::BYTEIN() { m_C = m_C + 0xff00 - (m_B << 8); m_CT = 8; } + + if (!m_pStream->IsInBounds()) + m_Complete = true; } void CJBig2_ArithDecoder::ReadValueA() { diff --git a/core/fxcodec/jbig2/JBig2_ArithDecoder.h b/core/fxcodec/jbig2/JBig2_ArithDecoder.h index a8ab5dd730..24fb80cfbd 100644 --- a/core/fxcodec/jbig2/JBig2_ArithDecoder.h +++ b/core/fxcodec/jbig2/JBig2_ArithDecoder.h @@ -7,6 +7,8 @@ #ifndef CORE_FXCODEC_JBIG2_JBIG2_ARITHDECODER_H_ #define CORE_FXCODEC_JBIG2_JBIG2_ARITHDECODER_H_ +#include + class CJBig2_BitStream; struct JBig2ArithCtx { @@ -24,11 +26,14 @@ class CJBig2_ArithDecoder { int DECODE(JBig2ArithCtx* pCX); + bool IsComplete() const { return m_Complete; } + private: void BYTEIN(); void ReadValueA(); - unsigned char m_B; + bool m_Complete; + uint8_t m_B; unsigned int m_C; unsigned int m_A; unsigned int m_CT; diff --git a/core/fxcodec/jbig2/JBig2_BitStream.cpp b/core/fxcodec/jbig2/JBig2_BitStream.cpp index 3346521aca..67d82f49a7 100644 --- a/core/fxcodec/jbig2/JBig2_BitStream.cpp +++ b/core/fxcodec/jbig2/JBig2_BitStream.cpp @@ -27,7 +27,7 @@ CJBig2_BitStream::CJBig2_BitStream(CPDF_StreamAcc* pSrcStream) CJBig2_BitStream::~CJBig2_BitStream() {} int32_t CJBig2_BitStream::readNBits(uint32_t dwBits, uint32_t* dwResult) { - if (!IsInBound()) + if (!IsInBounds()) return -1; uint32_t dwBitPos = getBitPos(); @@ -49,7 +49,7 @@ int32_t CJBig2_BitStream::readNBits(uint32_t dwBits, uint32_t* dwResult) { } int32_t CJBig2_BitStream::readNBits(uint32_t dwBits, int32_t* nResult) { - if (!IsInBound()) + if (!IsInBounds()) return -1; uint32_t dwBitPos = getBitPos(); @@ -71,7 +71,7 @@ int32_t CJBig2_BitStream::readNBits(uint32_t dwBits, int32_t* nResult) { } int32_t CJBig2_BitStream::read1Bit(uint32_t* dwResult) { - if (!IsInBound()) + if (!IsInBounds()) return -1; *dwResult = (m_pBuf[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01; @@ -80,7 +80,7 @@ int32_t CJBig2_BitStream::read1Bit(uint32_t* dwResult) { } int32_t CJBig2_BitStream::read1Bit(bool* bResult) { - if (!IsInBound()) + if (!IsInBounds()) return -1; *bResult = (m_pBuf[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01; @@ -89,7 +89,7 @@ int32_t CJBig2_BitStream::read1Bit(bool* bResult) { } int32_t CJBig2_BitStream::read1Byte(uint8_t* cResult) { - if (!IsInBound()) + if (!IsInBounds()) return -1; *cResult = m_pBuf[m_dwByteIdx]; @@ -124,16 +124,16 @@ void CJBig2_BitStream::alignByte() { } uint8_t CJBig2_BitStream::getCurByte() const { - return IsInBound() ? m_pBuf[m_dwByteIdx] : 0; + return IsInBounds() ? m_pBuf[m_dwByteIdx] : 0; } void CJBig2_BitStream::incByteIdx() { - if (IsInBound()) + if (IsInBounds()) ++m_dwByteIdx; } uint8_t CJBig2_BitStream::getCurByte_arith() const { - return IsInBound() ? m_pBuf[m_dwByteIdx] : 0xFF; + return IsInBounds() ? m_pBuf[m_dwByteIdx] : 0xFF; } uint8_t CJBig2_BitStream::getNextByte_arith() const { @@ -182,7 +182,7 @@ void CJBig2_BitStream::AdvanceBit() { } } -bool CJBig2_BitStream::IsInBound() const { +bool CJBig2_BitStream::IsInBounds() const { return m_dwByteIdx < m_dwLength; } diff --git a/core/fxcodec/jbig2/JBig2_BitStream.h b/core/fxcodec/jbig2/JBig2_BitStream.h index aeb2eba693..551b7df9b1 100644 --- a/core/fxcodec/jbig2/JBig2_BitStream.h +++ b/core/fxcodec/jbig2/JBig2_BitStream.h @@ -40,9 +40,10 @@ class CJBig2_BitStream { uint32_t getByteLeft() const; uint32_t getObjNum() const; + bool IsInBounds() const; + private: void AdvanceBit(); - bool IsInBound() const; uint32_t LengthInBits() const; const uint8_t* m_pBuf; diff --git a/core/fxcodec/jbig2/JBig2_GrdProc.cpp b/core/fxcodec/jbig2/JBig2_GrdProc.cpp index 8c6d58e511..d5d4c6d0dc 100644 --- a/core/fxcodec/jbig2/JBig2_GrdProc.cpp +++ b/core/fxcodec/jbig2/JBig2_GrdProc.cpp @@ -77,8 +77,12 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template0_opt3( int32_t nBitsLeft = GBW - (nLineBytes << 3); uint32_t height = GBH & 0x7fffffff; for (uint32_t h = 0; h < height; h++) { - if (TPGDON) + if (TPGDON) { + if (pArithDecoder->IsComplete()) + return nullptr; + LTP = LTP ^ pArithDecoder->DECODE(&gbContext[0x9b25]); + } if (LTP) { GBREG->copyLine(h, h - 1); } else { @@ -93,6 +97,9 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template0_opt3( line2 = (line2 << 8) | (*pLine2++); uint8_t cVal = 0; for (int32_t k = 7; k >= 0; k--) { + if (pArithDecoder->IsComplete()) + return nullptr; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal |= bVal << k; CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal | @@ -104,6 +111,9 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template0_opt3( line2 <<= 8; uint8_t cVal1 = 0; for (int32_t k = 0; k < nBitsLeft; k++) { + if (pArithDecoder->IsComplete()) + return nullptr; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal1 |= bVal << (7 - k); CONTEXT = @@ -121,6 +131,9 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template0_opt3( } uint8_t cVal = 0; for (int32_t k = 7; k >= 0; k--) { + if (pArithDecoder->IsComplete()) + return nullptr; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal |= bVal << k; CONTEXT = @@ -131,6 +144,9 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template0_opt3( line2 <<= 8; uint8_t cVal1 = 0; for (int32_t k = 0; k < nBitsLeft; k++) { + if (pArithDecoder->IsComplete()) + return nullptr; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal1 |= bVal << (7 - k); CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal | @@ -151,8 +167,12 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template0_unopt( std::unique_ptr GBREG(new CJBig2_Image(GBW, GBH)); GBREG->fill(0); for (uint32_t h = 0; h < GBH; h++) { - if (TPGDON) + if (TPGDON) { + if (pArithDecoder->IsComplete()) + return nullptr; + LTP = LTP ^ pArithDecoder->DECODE(&gbContext[0x9b25]); + } if (LTP) { GBREG->copyLine(h, h - 1); } else { @@ -174,6 +194,9 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template0_unopt( CONTEXT |= GBREG->getPixel(w + GBAT[4], h + GBAT[5]) << 11; CONTEXT |= line1 << 12; CONTEXT |= GBREG->getPixel(w + GBAT[6], h + GBAT[7]) << 15; + if (pArithDecoder->IsComplete()) + return nullptr; + bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); } if (bVal) { @@ -202,8 +225,12 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template1_opt3( int32_t nLineBytes = ((GBW + 7) >> 3) - 1; int32_t nBitsLeft = GBW - (nLineBytes << 3); for (uint32_t h = 0; h < GBH; h++) { - if (TPGDON) + if (TPGDON) { + if (pArithDecoder->IsComplete()) + return nullptr; + LTP = LTP ^ pArithDecoder->DECODE(&gbContext[0x0795]); + } if (LTP) { GBREG->copyLine(h, h - 1); } else { @@ -218,6 +245,9 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template1_opt3( line2 = (line2 << 8) | (*pLine2++); uint8_t cVal = 0; for (int32_t k = 7; k >= 0; k--) { + if (pArithDecoder->IsComplete()) + return nullptr; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal |= bVal << k; CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal | @@ -229,6 +259,9 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template1_opt3( line2 <<= 8; uint8_t cVal1 = 0; for (int32_t k = 0; k < nBitsLeft; k++) { + if (pArithDecoder->IsComplete()) + return nullptr; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal1 |= bVal << (7 - k); CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal | @@ -246,6 +279,9 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template1_opt3( } uint8_t cVal = 0; for (int32_t k = 7; k >= 0; k--) { + if (pArithDecoder->IsComplete()) + return nullptr; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal |= bVal << k; CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal | @@ -256,6 +292,9 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template1_opt3( line2 <<= 8; uint8_t cVal1 = 0; for (int32_t k = 0; k < nBitsLeft; k++) { + if (pArithDecoder->IsComplete()) + return nullptr; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal1 |= bVal << (7 - k); CONTEXT = @@ -276,8 +315,12 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template1_unopt( std::unique_ptr GBREG(new CJBig2_Image(GBW, GBH)); GBREG->fill(0); for (uint32_t h = 0; h < GBH; h++) { - if (TPGDON) + if (TPGDON) { + if (pArithDecoder->IsComplete()) + return nullptr; + LTP = LTP ^ pArithDecoder->DECODE(&gbContext[0x0795]); + } if (LTP) { GBREG->copyLine(h, h - 1); } else { @@ -297,6 +340,9 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template1_unopt( CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 3; CONTEXT |= line2 << 4; CONTEXT |= line1 << 9; + if (pArithDecoder->IsComplete()) + return nullptr; + bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); } if (bVal) { @@ -325,8 +371,12 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template2_opt3( int32_t nLineBytes = ((GBW + 7) >> 3) - 1; int32_t nBitsLeft = GBW - (nLineBytes << 3); for (uint32_t h = 0; h < GBH; h++) { - if (TPGDON) + if (TPGDON) { + if (pArithDecoder->IsComplete()) + return nullptr; + LTP = LTP ^ pArithDecoder->DECODE(&gbContext[0x00e5]); + } if (LTP) { GBREG->copyLine(h, h - 1); } else { @@ -341,6 +391,9 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template2_opt3( line2 = (line2 << 8) | (*pLine2++); uint8_t cVal = 0; for (int32_t k = 7; k >= 0; k--) { + if (pArithDecoder->IsComplete()) + return nullptr; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal |= bVal << k; CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal | @@ -352,6 +405,9 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template2_opt3( line2 <<= 8; uint8_t cVal1 = 0; for (int32_t k = 0; k < nBitsLeft; k++) { + if (pArithDecoder->IsComplete()) + return nullptr; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal1 |= bVal << (7 - k); CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal | @@ -369,6 +425,9 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template2_opt3( } uint8_t cVal = 0; for (int32_t k = 7; k >= 0; k--) { + if (pArithDecoder->IsComplete()) + return nullptr; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal |= bVal << k; CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal | @@ -379,6 +438,9 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template2_opt3( line2 <<= 8; uint8_t cVal1 = 0; for (int32_t k = 0; k < nBitsLeft; k++) { + if (pArithDecoder->IsComplete()) + return nullptr; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal1 |= bVal << (7 - k); CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal | @@ -399,8 +461,12 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template2_unopt( std::unique_ptr GBREG(new CJBig2_Image(GBW, GBH)); GBREG->fill(0); for (uint32_t h = 0; h < GBH; h++) { - if (TPGDON) + if (TPGDON) { + if (pArithDecoder->IsComplete()) + return nullptr; + LTP = LTP ^ pArithDecoder->DECODE(&gbContext[0x00e5]); + } if (LTP) { GBREG->copyLine(h, h - 1); } else { @@ -418,6 +484,9 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template2_unopt( CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 2; CONTEXT |= line2 << 3; CONTEXT |= line1 << 7; + if (pArithDecoder->IsComplete()) + return nullptr; + bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); } if (bVal) { @@ -444,9 +513,15 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template3_opt3( int32_t nStride = GBREG->stride(); int32_t nLineBytes = ((GBW + 7) >> 3) - 1; int32_t nBitsLeft = GBW - (nLineBytes << 3); + for (uint32_t h = 0; h < GBH; h++) { - if (TPGDON) + if (TPGDON) { + if (pArithDecoder->IsComplete()) + return nullptr; + LTP = LTP ^ pArithDecoder->DECODE(&gbContext[0x0195]); + } + if (LTP) { GBREG->copyLine(h, h - 1); } else { @@ -458,6 +533,9 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template3_opt3( line1 = (line1 << 8) | (*pLine1++); uint8_t cVal = 0; for (int32_t k = 7; k >= 0; k--) { + if (pArithDecoder->IsComplete()) + return nullptr; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal |= bVal << k; CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal | @@ -468,6 +546,9 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template3_opt3( line1 <<= 8; uint8_t cVal1 = 0; for (int32_t k = 0; k < nBitsLeft; k++) { + if (pArithDecoder->IsComplete()) + return nullptr; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal1 |= bVal << (7 - k); CONTEXT = @@ -479,6 +560,9 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template3_opt3( for (int32_t cc = 0; cc < nLineBytes; cc++) { uint8_t cVal = 0; for (int32_t k = 7; k >= 0; k--) { + if (pArithDecoder->IsComplete()) + return nullptr; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal |= bVal << k; CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal; @@ -487,6 +571,9 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template3_opt3( } uint8_t cVal1 = 0; for (int32_t k = 0; k < nBitsLeft; k++) { + if (pArithDecoder->IsComplete()) + return nullptr; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal1 |= bVal << (7 - k); CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal; @@ -506,8 +593,12 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template3_unopt( std::unique_ptr GBREG(new CJBig2_Image(GBW, GBH)); GBREG->fill(0); for (uint32_t h = 0; h < GBH; h++) { - if (TPGDON) + if (TPGDON) { + if (pArithDecoder->IsComplete()) + return nullptr; + LTP = LTP ^ pArithDecoder->DECODE(&gbContext[0x0195]); + } if (LTP == 1) { GBREG->copyLine(h, h - 1); } else { @@ -522,6 +613,9 @@ CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template3_unopt( uint32_t CONTEXT = line2; CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4; CONTEXT |= line1 << 5; + if (pArithDecoder->IsComplete()) + return nullptr; + bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); } if (bVal) { @@ -658,9 +752,14 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template0_opt3( int32_t nLineBytes = ((GBW + 7) >> 3) - 1; int32_t nBitsLeft = GBW - (nLineBytes << 3); uint32_t height = GBH & 0x7fffffff; + for (; m_loopIndex < height; m_loopIndex++) { - if (TPGDON) + if (TPGDON) { + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + m_LTP = m_LTP ^ pArithDecoder->DECODE(&gbContext[0x9b25]); + } if (m_LTP) { pImage->copyLine(m_loopIndex, m_loopIndex - 1); } else { @@ -675,6 +774,9 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template0_opt3( line2 = (line2 << 8) | (*pLine2++); uint8_t cVal = 0; for (int32_t k = 7; k >= 0; k--) { + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal |= bVal << k; CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal | @@ -686,6 +788,9 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template0_opt3( line2 <<= 8; uint8_t cVal1 = 0; for (int32_t k = 0; k < nBitsLeft; k++) { + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal1 |= bVal << (7 - k); CONTEXT = @@ -703,6 +808,9 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template0_opt3( } uint8_t cVal = 0; for (int32_t k = 7; k >= 0; k--) { + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal |= bVal << k; CONTEXT = @@ -713,6 +821,9 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template0_opt3( line2 <<= 8; uint8_t cVal1 = 0; for (int32_t k = 0; k < nBitsLeft; k++) { + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal1 |= bVal << (7 - k); CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal | @@ -738,8 +849,12 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template0_unopt( JBig2ArithCtx* gbContext, IFX_Pause* pPause) { for (; m_loopIndex < GBH; m_loopIndex++) { - if (TPGDON) + if (TPGDON) { + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + m_LTP = m_LTP ^ pArithDecoder->DECODE(&gbContext[0x9b25]); + } if (m_LTP) { pImage->copyLine(m_loopIndex, m_loopIndex - 1); } else { @@ -761,6 +876,9 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template0_unopt( CONTEXT |= pImage->getPixel(w + GBAT[4], m_loopIndex + GBAT[5]) << 11; CONTEXT |= line1 << 12; CONTEXT |= pImage->getPixel(w + GBAT[6], m_loopIndex + GBAT[7]) << 15; + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); } if (bVal) { @@ -796,8 +914,12 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template1_opt3( int32_t nLineBytes = ((GBW + 7) >> 3) - 1; int32_t nBitsLeft = GBW - (nLineBytes << 3); for (; m_loopIndex < GBH; m_loopIndex++) { - if (TPGDON) + if (TPGDON) { + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + m_LTP = m_LTP ^ pArithDecoder->DECODE(&gbContext[0x0795]); + } if (m_LTP) { pImage->copyLine(m_loopIndex, m_loopIndex - 1); } else { @@ -812,6 +934,9 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template1_opt3( line2 = (line2 << 8) | (*pLine2++); uint8_t cVal = 0; for (int32_t k = 7; k >= 0; k--) { + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal |= bVal << k; CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal | @@ -823,6 +948,9 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template1_opt3( line2 <<= 8; uint8_t cVal1 = 0; for (int32_t k = 0; k < nBitsLeft; k++) { + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal1 |= bVal << (7 - k); CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal | @@ -840,6 +968,9 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template1_opt3( } uint8_t cVal = 0; for (int32_t k = 7; k >= 0; k--) { + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal |= bVal << k; CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal | @@ -850,6 +981,9 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template1_opt3( line2 <<= 8; uint8_t cVal1 = 0; for (int32_t k = 0; k < nBitsLeft; k++) { + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal1 |= bVal << (7 - k); CONTEXT = @@ -875,8 +1009,12 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template1_unopt( JBig2ArithCtx* gbContext, IFX_Pause* pPause) { for (uint32_t h = 0; h < GBH; h++) { - if (TPGDON) + if (TPGDON) { + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + m_LTP = m_LTP ^ pArithDecoder->DECODE(&gbContext[0x0795]); + } if (m_LTP) { pImage->copyLine(h, h - 1); } else { @@ -896,6 +1034,9 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template1_unopt( CONTEXT |= pImage->getPixel(w + GBAT[0], h + GBAT[1]) << 3; CONTEXT |= line2 << 4; CONTEXT |= line1 << 9; + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); } if (bVal) { @@ -929,8 +1070,12 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template2_opt3( int32_t nLineBytes = ((GBW + 7) >> 3) - 1; int32_t nBitsLeft = GBW - (nLineBytes << 3); for (; m_loopIndex < GBH; m_loopIndex++) { - if (TPGDON) + if (TPGDON) { + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + m_LTP = m_LTP ^ pArithDecoder->DECODE(&gbContext[0x00e5]); + } if (m_LTP) { pImage->copyLine(m_loopIndex, m_loopIndex - 1); } else { @@ -945,6 +1090,9 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template2_opt3( line2 = (line2 << 8) | (*pLine2++); uint8_t cVal = 0; for (int32_t k = 7; k >= 0; k--) { + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal |= bVal << k; CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal | @@ -956,6 +1104,9 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template2_opt3( line2 <<= 8; uint8_t cVal1 = 0; for (int32_t k = 0; k < nBitsLeft; k++) { + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal1 |= bVal << (7 - k); CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal | @@ -973,6 +1124,9 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template2_opt3( } uint8_t cVal = 0; for (int32_t k = 7; k >= 0; k--) { + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal |= bVal << k; CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal | @@ -983,6 +1137,9 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template2_opt3( line2 <<= 8; uint8_t cVal1 = 0; for (int32_t k = 0; k < nBitsLeft; k++) { + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal1 |= bVal << (7 - k); CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal | @@ -1008,8 +1165,12 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template2_unopt( JBig2ArithCtx* gbContext, IFX_Pause* pPause) { for (; m_loopIndex < GBH; m_loopIndex++) { - if (TPGDON) + if (TPGDON) { + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + m_LTP = m_LTP ^ pArithDecoder->DECODE(&gbContext[0x00e5]); + } if (m_LTP) { pImage->copyLine(m_loopIndex, m_loopIndex - 1); } else { @@ -1027,6 +1188,9 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template2_unopt( CONTEXT |= pImage->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 2; CONTEXT |= line2 << 3; CONTEXT |= line1 << 7; + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); } if (bVal) { @@ -1061,8 +1225,12 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template3_opt3( int32_t nLineBytes = ((GBW + 7) >> 3) - 1; int32_t nBitsLeft = GBW - (nLineBytes << 3); for (; m_loopIndex < GBH; m_loopIndex++) { - if (TPGDON) + if (TPGDON) { + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + m_LTP = m_LTP ^ pArithDecoder->DECODE(&gbContext[0x0195]); + } if (m_LTP) { pImage->copyLine(m_loopIndex, m_loopIndex - 1); } else { @@ -1074,6 +1242,9 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template3_opt3( line1 = (line1 << 8) | (*pLine1++); uint8_t cVal = 0; for (int32_t k = 7; k >= 0; k--) { + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal |= bVal << k; CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal | @@ -1084,6 +1255,9 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template3_opt3( line1 <<= 8; uint8_t cVal1 = 0; for (int32_t k = 0; k < nBitsLeft; k++) { + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal1 |= bVal << (7 - k); CONTEXT = @@ -1095,6 +1269,9 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template3_opt3( for (int32_t cc = 0; cc < nLineBytes; cc++) { uint8_t cVal = 0; for (int32_t k = 7; k >= 0; k--) { + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal |= bVal << k; CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal; @@ -1103,6 +1280,9 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template3_opt3( } uint8_t cVal1 = 0; for (int32_t k = 0; k < nBitsLeft; k++) { + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + int bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); cVal1 |= bVal << (7 - k); CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal; @@ -1127,8 +1307,12 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template3_unopt( JBig2ArithCtx* gbContext, IFX_Pause* pPause) { for (; m_loopIndex < GBH; m_loopIndex++) { - if (TPGDON) + if (TPGDON) { + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + m_LTP = m_LTP ^ pArithDecoder->DECODE(&gbContext[0x0195]); + } if (m_LTP) { pImage->copyLine(m_loopIndex, m_loopIndex - 1); } else { @@ -1143,6 +1327,9 @@ FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template3_unopt( uint32_t CONTEXT = line2; CONTEXT |= pImage->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 4; CONTEXT |= line1 << 5; + if (pArithDecoder->IsComplete()) + return FXCODEC_STATUS_ERROR; + bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]); } if (bVal) { -- cgit v1.2.3