diff options
author | Oliver Chang <ochang@chromium.org> | 2015-11-13 16:16:48 -0800 |
---|---|---|
committer | Oliver Chang <ochang@chromium.org> | 2015-11-13 16:16:48 -0800 |
commit | 159121f4ff2b65455d602bae2750d83ec535e764 (patch) | |
tree | 37c559a3384dbbf031a1d100c8e783ddda7a88e7 | |
parent | df8fedd330e1e9916d96cefa9c2c39846bff97e9 (diff) | |
download | pdfium-159121f4ff2b65455d602bae2750d83ec535e764.tar.xz |
Merge to M47: Clear decoders after the image decoder in the /Filter array.
During decoding, when an image decoder is encountered, any
subsequent decoders are ignored, but remain in the array. However,
later on CPDF_DIBSource::ValidateDictParam expects the image
decoder to be the last in the array, causing issues.
A check is also added in CPDF_DIBSource::GetScanline to ensure
that the calculated pitch value is <= the (4-aligned) pitch value in the
cached bitmap to prevent future issues.
Also cleans up some NULL usages.
BUG=552046
Review URL: https://codereview.chromium.org/1406943005 .
(cherry picked from commit 182d129bcee8f7731b9bbfde0064295ad3b37271)
R=thestig@chromium.org
Review URL: https://codereview.chromium.org/1444503002 .
-rw-r--r-- | core/include/fpdfapi/fpdf_objects.h | 2 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_parser/fpdf_parser_decode.cpp | 11 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp | 17 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp | 10 |
4 files changed, 24 insertions, 16 deletions
diff --git a/core/include/fpdfapi/fpdf_objects.h b/core/include/fpdfapi/fpdf_objects.h index c2d838d35b..0778799eab 100644 --- a/core/include/fpdfapi/fpdf_objects.h +++ b/core/include/fpdfapi/fpdf_objects.h @@ -267,7 +267,7 @@ class CPDF_Array : public CPDF_Object { CPDF_Object* pObj, CPDF_IndirectObjects* pObjs = NULL); - void RemoveAt(FX_DWORD index); + void RemoveAt(FX_DWORD index, int nCount = 1); void Add(CPDF_Object* pObj, CPDF_IndirectObjects* pObjs = NULL); diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode.cpp index 2d6e9f3436..1633314bfd 100644 --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode.cpp +++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode.cpp @@ -398,18 +398,23 @@ FX_BOOL PDF_DataDecode(const uint8_t* src_buf, return TRUE; } offset = RunLengthDecode(last_buf, last_size, new_buf, new_size); + } else if (decoder == FX_BSTRC("Crypt")) { + continue; } else { + // If we get here, assume it's an image decoder. if (decoder == FX_BSTRC("DCT")) { decoder = "DCTDecode"; } else if (decoder == FX_BSTRC("CCF")) { decoder = "CCITTFaxDecode"; - } else if (decoder == FX_BSTRC("Crypt")) { - continue; } ImageEncoding = decoder; pImageParms = pParam; dest_buf = (uint8_t*)last_buf; dest_size = last_size; + if (pDecoder->GetType() == PDFOBJ_ARRAY) { + CPDF_Array* pDecoders = reinterpret_cast<CPDF_Array*>(pDecoder); + pDecoders->RemoveAt(i + 1, pDecoders->GetCount() - i - 1); + } return TRUE; } if (last_buf != src_buf) { @@ -423,7 +428,7 @@ FX_BOOL PDF_DataDecode(const uint8_t* src_buf, last_size = new_size; } ImageEncoding = ""; - pImageParms = NULL; + pImageParms = nullptr; dest_buf = last_buf; dest_size = last_size; return TRUE; diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp index e1e821c4c5..7baa2528a0 100644 --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp +++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp @@ -464,15 +464,18 @@ CPDF_Array* CPDF_Array::GetArray(FX_DWORD i) const { } return (CPDF_Array*)p; } -void CPDF_Array::RemoveAt(FX_DWORD i) { - ASSERT(m_Type == PDFOBJ_ARRAY); - if (i >= (FX_DWORD)m_Objects.GetSize()) { +void CPDF_Array::RemoveAt(FX_DWORD i, int nCount) { + if (i >= (FX_DWORD)m_Objects.GetSize()) + return; + + if (nCount <= 0 || nCount > m_Objects.GetSize() - i) return; + + for (int j = 0; j < nCount; ++j) { + if (CPDF_Object* p = static_cast<CPDF_Object*>(m_Objects.GetAt(i + j))) + p->Release(); } - CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i); - if (p) - p->Release(); - m_Objects.RemoveAt(i); + m_Objects.RemoveAt(i, nCount); } void CPDF_Array::SetAt(FX_DWORD i, CPDF_Object* pObj, diff --git a/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp b/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp index f1fbf41d6d..17d5f884ca 100644 --- a/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp +++ b/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp @@ -1098,14 +1098,14 @@ uint8_t* CPDF_DIBSource::GetBuffer() const { } const uint8_t* CPDF_DIBSource::GetScanline(int line) const { if (m_bpc == 0) { - return NULL; + return nullptr; } FX_SAFE_DWORD src_pitch = CalculatePitch8(m_bpc, m_nComponents, m_Width, 1); if (!src_pitch.IsValid()) - return NULL; + return nullptr; FX_DWORD src_pitch_value = src_pitch.ValueOrDie(); - const uint8_t* pSrcLine = NULL; - if (m_pCachedBitmap) { + const uint8_t* pSrcLine = nullptr; + if (m_pCachedBitmap && src_pitch_value <= m_pCachedBitmap->GetPitch()) { if (line >= m_pCachedBitmap->GetHeight()) { line = m_pCachedBitmap->GetHeight() - 1; } @@ -1117,7 +1117,7 @@ const uint8_t* CPDF_DIBSource::GetScanline(int line) const { pSrcLine = m_pStreamAcc->GetData() + line * src_pitch_value; } } - if (pSrcLine == NULL) { + if (!pSrcLine) { uint8_t* pLineBuf = m_pMaskedLine ? m_pMaskedLine : m_pLineBuf; FXSYS_memset(pLineBuf, 0xFF, m_Pitch); return pLineBuf; |