From 89d8b4681ce98894a1ee1a6cf4bae77e00d28797 Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Thu, 10 Sep 2015 16:13:31 -0700 Subject: Guard against null image data in CJBig2_GRRDProc. Credit to karl at skomski.com for the initial version of the CL. BUG=527174 R=tsepez@chromium.org Review URL: https://codereview.chromium.org/1305033006 . --- core/src/fxcodec/jbig2/JBig2_Context.cpp | 65 +++++++++------------ core/src/fxcodec/jbig2/JBig2_GeneralDecoder.cpp | 6 ++ testing/resources/pixel/bug_527174.in | Bin 0 -> 693 bytes .../resources/pixel/bug_527174_expected.pdf.0.png | Bin 0 -> 3650 bytes 4 files changed, 35 insertions(+), 36 deletions(-) create mode 100644 testing/resources/pixel/bug_527174.in create mode 100644 testing/resources/pixel/bug_527174_expected.pdf.0.png diff --git a/core/src/fxcodec/jbig2/JBig2_Context.cpp b/core/src/fxcodec/jbig2/JBig2_Context.cpp index f045dbb20d..232bbf26af 100644 --- a/core/src/fxcodec/jbig2/JBig2_Context.cpp +++ b/core/src/fxcodec/jbig2/JBig2_Context.cpp @@ -402,6 +402,7 @@ int32_t CJBig2_Context::parseSegmentHeader(CJBig2_Segment* pSegment) { failed: return JBIG2_ERROR_TOO_SHORT; } + int32_t CJBig2_Context::parseSegmentData(CJBig2_Segment* pSegment, IFX_Pause* pPause) { int32_t ret = ProcessiveParseSegmentData(pSegment, pPause); @@ -411,6 +412,7 @@ int32_t CJBig2_Context::parseSegmentData(CJBig2_Segment* pSegment, } return ret; } + int32_t CJBig2_Context::ProcessiveParseSegmentData(CJBig2_Segment* pSegment, IFX_Pause* pPause) { switch (pSegment->m_cFlags.s.type) { @@ -419,37 +421,29 @@ int32_t CJBig2_Context::ProcessiveParseSegmentData(CJBig2_Segment* pSegment, case 4: case 6: case 7: - if (m_nState == JBIG2_OUT_OF_PAGE) { - goto failed2; - } else { - return parseTextRegion(pSegment); - } + if (m_nState == JBIG2_OUT_OF_PAGE) + return JBIG2_ERROR_FATAL; + return parseTextRegion(pSegment); case 16: return parsePatternDict(pSegment, pPause); case 20: case 22: case 23: - if (m_nState == JBIG2_OUT_OF_PAGE) { - goto failed2; - } else { - return parseHalftoneRegion(pSegment, pPause); - } + if (m_nState == JBIG2_OUT_OF_PAGE) + return JBIG2_ERROR_FATAL; + return parseHalftoneRegion(pSegment, pPause); case 36: case 38: case 39: - if (m_nState == JBIG2_OUT_OF_PAGE) { - goto failed2; - } else { - return parseGenericRegion(pSegment, pPause); - } + if (m_nState == JBIG2_OUT_OF_PAGE) + return JBIG2_ERROR_FATAL; + return parseGenericRegion(pSegment, pPause); case 40: case 42: case 43: - if (m_nState == JBIG2_OUT_OF_PAGE) { - goto failed2; - } else { - return parseGenericRefinementRegion(pSegment); - } + if (m_nState == JBIG2_OUT_OF_PAGE) + return JBIG2_ERROR_FATAL; + return parseGenericRefinementRegion(pSegment); case 48: { FX_WORD wTemp; nonstd::unique_ptr pPageInfo(new JBig2PageInfo); @@ -459,24 +453,26 @@ int32_t CJBig2_Context::ProcessiveParseSegmentData(CJBig2_Segment* pSegment, (m_pStream->readInteger(&pPageInfo->m_dwResolutionY) != 0) || (m_pStream->read1Byte(&pPageInfo->m_cFlags) != 0) || (m_pStream->readShortInteger(&wTemp) != 0)) { - goto failed1; + return JBIG2_ERROR_TOO_SHORT; } - pPageInfo->m_bIsStriped = ((wTemp >> 15) & 1) ? 1 : 0; + pPageInfo->m_bIsStriped = ((wTemp >> 15) & 1) ? TRUE : FALSE; pPageInfo->m_wMaxStripeSize = wTemp & 0x7fff; - if ((pPageInfo->m_dwHeight == 0xffffffff) && - (pPageInfo->m_bIsStriped != TRUE)) { + bool bMaxHeight = (pPageInfo->m_dwHeight == 0xffffffff); + if (bMaxHeight && pPageInfo->m_bIsStriped != TRUE) pPageInfo->m_bIsStriped = TRUE; - } + if (!m_bBufSpecified) { delete m_pPage; - if (pPageInfo->m_dwHeight == 0xffffffff) { - m_pPage = new CJBig2_Image(pPageInfo->m_dwWidth, - pPageInfo->m_wMaxStripeSize); - } else { - m_pPage = - new CJBig2_Image(pPageInfo->m_dwWidth, pPageInfo->m_dwHeight); - } + FX_DWORD height = + bMaxHeight ? pPageInfo->m_wMaxStripeSize : pPageInfo->m_dwHeight; + m_pPage = new CJBig2_Image(pPageInfo->m_dwWidth, height); + } + + if (!m_pPage->m_pData) { + m_ProcessiveStatus = FXCODEC_STATUS_ERROR; + return JBIG2_ERROR_TOO_SHORT; } + m_pPage->fill((pPageInfo->m_cFlags & 4) ? 1 : 0); m_PageInfoList.push_back(pPageInfo.release()); m_nState = JBIG2_IN_PAGE; @@ -502,11 +498,8 @@ int32_t CJBig2_Context::ProcessiveParseSegmentData(CJBig2_Segment* pSegment, break; } return JBIG2_SUCCESS; -failed1: - return JBIG2_ERROR_TOO_SHORT; -failed2: - return JBIG2_ERROR_FATAL; } + int32_t CJBig2_Context::parseSymbolDict(CJBig2_Segment* pSegment, IFX_Pause* pPause) { FX_DWORD dwTemp; diff --git a/core/src/fxcodec/jbig2/JBig2_GeneralDecoder.cpp b/core/src/fxcodec/jbig2/JBig2_GeneralDecoder.cpp index 2e558ee7e8..1c56db984b 100644 --- a/core/src/fxcodec/jbig2/JBig2_GeneralDecoder.cpp +++ b/core/src/fxcodec/jbig2/JBig2_GeneralDecoder.cpp @@ -719,6 +719,9 @@ CJBig2_Image* CJBig2_GRRDProc::decode_Template0_unopt( CJBig2_Image* CJBig2_GRRDProc::decode_Template0_opt( CJBig2_ArithDecoder* pArithDecoder, JBig2ArithCtx* grContext) { + if (!GRREFERENCE->m_pData) + return nullptr; + FX_BOOL LTP, SLTP, bVal; FX_DWORD CONTEXT; FX_DWORD line1, line1_r, line2_r, line3_r; @@ -953,6 +956,9 @@ CJBig2_Image* CJBig2_GRRDProc::decode_Template1_unopt( CJBig2_Image* CJBig2_GRRDProc::decode_Template1_opt( CJBig2_ArithDecoder* pArithDecoder, JBig2ArithCtx* grContext) { + if (!GRREFERENCE->m_pData) + return nullptr; + FX_BOOL LTP, SLTP, bVal; FX_DWORD CONTEXT; FX_DWORD line1, line1_r, line2_r, line3_r; diff --git a/testing/resources/pixel/bug_527174.in b/testing/resources/pixel/bug_527174.in new file mode 100644 index 0000000000..2b33e304c4 Binary files /dev/null and b/testing/resources/pixel/bug_527174.in differ diff --git a/testing/resources/pixel/bug_527174_expected.pdf.0.png b/testing/resources/pixel/bug_527174_expected.pdf.0.png new file mode 100644 index 0000000000..4035b7632c Binary files /dev/null and b/testing/resources/pixel/bug_527174_expected.pdf.0.png differ -- cgit v1.2.3