diff options
author | Oliver Chang <ochang@chromium.org> | 2015-11-24 12:24:23 -0800 |
---|---|---|
committer | Oliver Chang <ochang@chromium.org> | 2015-11-24 12:24:23 -0800 |
commit | e668838baf79ff8bc0e13931feea5cd1877706eb (patch) | |
tree | db8b3f4f994996fff4d91fd6e57688c47b0f7f5f | |
parent | 4ec1953b4ace8248ac443effafa5f651e540d995 (diff) | |
download | pdfium-e668838baf79ff8bc0e13931feea5cd1877706eb.tar.xz |
Merge to M47: Change |CCodec_ScanlineDecoder::m_Pitch| to FX_DWORD
This matches the type of the corresponding |CFX_DIBSource::m_Pitch|,
where integer overflow is checked for FX_DWORD. This change is
propagated to many other places.
Also, check for integer overflow in |CCodec_RLScanlineDecoder::Create|
during the calculation of |m_Pitch| since it aligns to 4 bytes while
overflow was was previously checked without this alignment.
TBR=thestig@chromium.org
BUG=555784
Original Review URL: https://codereview.chromium.org/1460033002 .
(cherry picked from commit e7950df70a2fd658f466751b29483436cb31e829)
Review URL: https://codereview.chromium.org/1473143003 .
-rw-r--r-- | core/src/fxcodec/codec/codec_int.h | 6 | ||||
-rw-r--r-- | core/src/fxcodec/codec/fx_codec.cpp | 23 | ||||
-rw-r--r-- | core/src/fxcodec/codec/fx_codec_fax.cpp | 5 | ||||
-rw-r--r-- | core/src/fxcodec/codec/fx_codec_flate.cpp | 26 | ||||
-rw-r--r-- | core/src/fxcodec/codec/fx_codec_jpeg.cpp | 6 |
5 files changed, 44 insertions, 22 deletions
diff --git a/core/src/fxcodec/codec/codec_int.h b/core/src/fxcodec/codec/codec_int.h index bc2aac883a..2910589b0a 100644 --- a/core/src/fxcodec/codec/codec_int.h +++ b/core/src/fxcodec/codec/codec_int.h @@ -57,7 +57,7 @@ class CCodec_ScanlineDecoder : public ICodec_ScanlineDecoder { protected: class ImageDataCache { public: - ImageDataCache(int width, int height, int pitch); + ImageDataCache(int width, int height, FX_DWORD pitch); ~ImageDataCache(); bool AllocateCache(); @@ -74,7 +74,7 @@ class CCodec_ScanlineDecoder : public ICodec_ScanlineDecoder { const int m_Width; const int m_Height; - const int m_Pitch; + const FX_DWORD m_Pitch; int m_nCachedLines; nonstd::unique_ptr<uint8_t, FxFreeDeleter> m_Data; }; @@ -92,7 +92,7 @@ class CCodec_ScanlineDecoder : public ICodec_ScanlineDecoder { int m_OutputHeight; int m_nComps; int m_bpc; - int m_Pitch; + FX_DWORD m_Pitch; FX_BOOL m_bColorTransformed; int m_NextLine; uint8_t* m_pLastScanline; diff --git a/core/src/fxcodec/codec/fx_codec.cpp b/core/src/fxcodec/codec/fx_codec.cpp index 46f479e0b1..9e284e489f 100644 --- a/core/src/fxcodec/codec/fx_codec.cpp +++ b/core/src/fxcodec/codec/fx_codec.cpp @@ -23,7 +23,7 @@ CCodec_ModuleMgr::CCodec_ModuleMgr() CCodec_ScanlineDecoder::ImageDataCache::ImageDataCache(int width, int height, - int pitch) + FX_DWORD pitch) : m_Width(width), m_Height(height), m_Pitch(pitch), m_nCachedLines(0) { } @@ -31,7 +31,7 @@ CCodec_ScanlineDecoder::ImageDataCache::~ImageDataCache() { } bool CCodec_ScanlineDecoder::ImageDataCache::AllocateCache() { - if (m_Pitch <= 0 || m_Height < 0) + if (m_Pitch == 0 || m_Height < 0) return false; FX_SAFE_SIZE_T size = m_Pitch; @@ -45,7 +45,7 @@ bool CCodec_ScanlineDecoder::ImageDataCache::AllocateCache() { void CCodec_ScanlineDecoder::ImageDataCache::AppendLine(const uint8_t* line) { // If the callers adds more lines than there is room, fail. - if (m_Pitch <= 0 || m_nCachedLines >= m_Height) { + if (m_Pitch == 0 || m_nCachedLines >= m_Height) { NOTREACHED(); return; } @@ -56,7 +56,7 @@ void CCodec_ScanlineDecoder::ImageDataCache::AppendLine(const uint8_t* line) { } const uint8_t* CCodec_ScanlineDecoder::ImageDataCache::GetLine(int line) const { - if (m_Pitch <= 0 || line < 0 || line >= m_nCachedLines) + if (m_Pitch == 0 || line < 0 || line >= m_nCachedLines) return nullptr; size_t offset = m_Pitch; @@ -338,8 +338,19 @@ FX_BOOL CCodec_RLScanlineDecoder::Create(const uint8_t* src_buf, m_bpc = bpc; m_bColorTransformed = FALSE; m_DownScale = 1; - m_Pitch = (width * nComps * bpc + 31) / 32 * 4; - m_dwLineBytes = (width * nComps * bpc + 7) / 8; + // Aligning the pitch to 4 bytes requires an integer overflow check. + FX_SAFE_DWORD pitch = width; + pitch *= nComps; + pitch *= bpc; + pitch += 31; + pitch /= 32; + pitch *= 4; + if (!pitch.IsValid()) { + return FALSE; + } + m_Pitch = pitch.ValueOrDie(); + // Overflow should already have been checked before this is called. + m_dwLineBytes = (static_cast<FX_DWORD>(width) * nComps * bpc + 7) / 8; m_pScanline = FX_Alloc(uint8_t, m_Pitch); return CheckDestSize(); } diff --git a/core/src/fxcodec/codec/fx_codec_fax.cpp b/core/src/fxcodec/codec/fx_codec_fax.cpp index 5af1d9e7ce..daa8a0713c 100644 --- a/core/src/fxcodec/codec/fx_codec_fax.cpp +++ b/core/src/fxcodec/codec/fx_codec_fax.cpp @@ -656,7 +656,8 @@ FX_BOOL CCodec_FaxDecoder::Create(const uint8_t* src_buf, if (m_OrigHeight == 0) { m_OrigHeight = height; } - m_Pitch = (m_OrigWidth + 31) / 32 * 4; + // Should not overflow. Checked by FPDFAPI_CreateFaxDecoder. + m_Pitch = (static_cast<FX_DWORD>(m_OrigWidth) + 31) / 32 * 4; m_OutputWidth = m_OrigWidth; m_OutputHeight = m_OrigHeight; m_pScanlineBuf = FX_Alloc(uint8_t, m_Pitch); @@ -716,7 +717,7 @@ uint8_t* CCodec_FaxDecoder::v_GetNextLine() { } } if (m_bBlack) { - for (int i = 0; i < m_Pitch; i++) { + for (FX_DWORD i = 0; i < m_Pitch; i++) { m_pScanlineBuf[i] = ~m_pScanlineBuf[i]; } } diff --git a/core/src/fxcodec/codec/fx_codec_flate.cpp b/core/src/fxcodec/codec/fx_codec_flate.cpp index 519ff00522..34356e1757 100644 --- a/core/src/fxcodec/codec/fx_codec_flate.cpp +++ b/core/src/fxcodec/codec/fx_codec_flate.cpp @@ -558,7 +558,7 @@ FX_BOOL TIFF_PredictorEncode(uint8_t*& data_buf, } void TIFF_PredictLine(uint8_t* dest_buf, - int row_size, + FX_DWORD row_size, int BitsPerComponent, int Colors, int Columns) { @@ -582,7 +582,7 @@ void TIFF_PredictLine(uint8_t* dest_buf, } int BytesPerPixel = BitsPerComponent * Colors / 8; if (BitsPerComponent == 16) { - for (int i = BytesPerPixel; i < row_size; i += 2) { + for (FX_DWORD i = BytesPerPixel; i < row_size; i += 2) { FX_WORD pixel = (dest_buf[i - BytesPerPixel] << 8) | dest_buf[i - BytesPerPixel + 1]; pixel += (dest_buf[i] << 8) | dest_buf[i + 1]; @@ -590,7 +590,7 @@ void TIFF_PredictLine(uint8_t* dest_buf, dest_buf[i + 1] = (uint8_t)pixel; } } else { - for (int i = BytesPerPixel; i < row_size; i++) { + for (FX_DWORD i = BytesPerPixel; i < row_size; i++) { dest_buf[i] += dest_buf[i - BytesPerPixel]; } } @@ -761,7 +761,11 @@ class CCodec_FlateScanlineDecoder : public CCodec_ScanlineDecoder { uint8_t* m_pPredictBuffer; uint8_t* m_pPredictRaw; int m_Predictor; - int m_Colors, m_BitsPerComponent, m_Columns, m_PredictPitch, m_LeftOver; + int m_Colors; + int m_BitsPerComponent; + int m_Columns; + FX_DWORD m_PredictPitch; + size_t m_LeftOver; }; CCodec_FlateScanlineDecoder::CCodec_FlateScanlineDecoder() { @@ -798,7 +802,7 @@ void CCodec_FlateScanlineDecoder::Create(const uint8_t* src_buf, m_nComps = nComps; m_bpc = bpc; m_bColorTransformed = FALSE; - m_Pitch = (width * nComps * bpc + 7) / 8; + m_Pitch = (static_cast<FX_DWORD>(width) * nComps * bpc + 7) / 8; m_pScanline = FX_Alloc(uint8_t, m_Pitch); m_Predictor = 0; if (predictor) { @@ -816,7 +820,10 @@ void CCodec_FlateScanlineDecoder::Create(const uint8_t* src_buf, m_Colors = Colors; m_BitsPerComponent = BitsPerComponent; m_Columns = Columns; - m_PredictPitch = (m_BitsPerComponent * m_Colors * m_Columns + 7) / 8; + m_PredictPitch = + (static_cast<FX_DWORD>(m_BitsPerComponent) * m_Colors * m_Columns + + 7) / + 8; m_pLastLine = FX_Alloc(uint8_t, m_PredictPitch); m_pPredictRaw = FX_Alloc(uint8_t, m_PredictPitch + 1); m_pPredictBuffer = FX_Alloc(uint8_t, m_PredictPitch); @@ -849,8 +856,9 @@ uint8_t* CCodec_FlateScanlineDecoder::v_GetNextLine() { m_OutputWidth); } } else { - int bytes_to_go = m_Pitch; - int read_leftover = m_LeftOver > bytes_to_go ? bytes_to_go : m_LeftOver; + size_t bytes_to_go = m_Pitch; + size_t read_leftover = + m_LeftOver > bytes_to_go ? bytes_to_go : m_LeftOver; if (read_leftover) { FXSYS_memcpy(m_pScanline, m_pPredictBuffer + m_PredictPitch - m_LeftOver, @@ -869,7 +877,7 @@ uint8_t* CCodec_FlateScanlineDecoder::v_GetNextLine() { TIFF_PredictLine(m_pPredictBuffer, m_PredictPitch, m_BitsPerComponent, m_Colors, m_Columns); } - int read_bytes = + size_t read_bytes = m_PredictPitch > bytes_to_go ? bytes_to_go : m_PredictPitch; FXSYS_memcpy(m_pScanline + m_Pitch - bytes_to_go, m_pPredictBuffer, read_bytes); diff --git a/core/src/fxcodec/codec/fx_codec_jpeg.cpp b/core/src/fxcodec/codec/fx_codec_jpeg.cpp index efd83f88ae..0a38fc82ca 100644 --- a/core/src/fxcodec/codec/fx_codec_jpeg.cpp +++ b/core/src/fxcodec/codec/fx_codec_jpeg.cpp @@ -426,7 +426,9 @@ FX_BOOL CCodec_JpegDecoder::Create(const uint8_t* src_buf, if ((int)cinfo.image_width < width) { return FALSE; } - m_Pitch = (cinfo.image_width * cinfo.num_components + 3) / 4 * 4; + m_Pitch = + (static_cast<FX_DWORD>(cinfo.image_width) * cinfo.num_components + 3) / + 4 * 4; m_pScanlineBuf = FX_Alloc(uint8_t, m_Pitch); m_nComps = cinfo.num_components; m_bpc = 8; @@ -464,7 +466,7 @@ void CCodec_JpegDecoder::v_DownScale(int dest_width, int dest_height) { FX_GetDownsampleRatio(m_OrigWidth, m_OrigHeight, dest_width, dest_height); m_OutputWidth = (m_OrigWidth + m_DownScale - 1) / m_DownScale; m_OutputHeight = (m_OrigHeight + m_DownScale - 1) / m_DownScale; - m_Pitch = (m_OutputWidth * m_nComps + 3) / 4 * 4; + m_Pitch = (static_cast<FX_DWORD>(m_OutputWidth) * m_nComps + 3) / 4 * 4; if (old_scale != m_DownScale) { m_NextLine = -1; } |