Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(814)

Side by Side Diff: core/fxcodec/jbig2/JBig2_Image.cpp

Issue 2202013002: Bound total pixels in JBig2 images to avoid overflows later. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 PDFium Authors. All rights reserved. 1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 6
7 #include <limits.h> 7 #include <limits.h>
8 8
9 #include "core/fxcodec/jbig2/JBig2_Image.h" 9 #include "core/fxcodec/jbig2/JBig2_Image.h"
10 #include "core/fxcrt/include/fx_coordinates.h" 10 #include "core/fxcrt/include/fx_coordinates.h"
11 #include "core/fxcrt/include/fx_safe_types.h" 11 #include "core/fxcrt/include/fx_safe_types.h"
12 12
13 CJBig2_Image::CJBig2_Image(int32_t w, int32_t h) { 13 namespace {
14
15 const int kMaxImageBytes = 100 * 1024 * 1024;
16 const int kMaxImagePixels = 8 * kMaxImageBytes;
17 static_assert(kMaxImagePixels < INT_MAX - 31,
18 "Pixel calculatons will overflow");
Lei Zhang 2016/08/01 22:49:50 Are calculatons cousins to Calculon?
Tom Sepez 2016/08/01 23:21:13 indeed. sadly this got removed and replaced by ju
19
20 } // namespace
21
22 CJBig2_Image::CJBig2_Image(int32_t w, int32_t h)
23 : m_pData(nullptr),
24 m_nWidth(0),
25 m_nHeight(0),
26 m_nStride(0),
27 m_bNeedFree(true) {
28 if (w < 0 || h < 0 || w > kMaxImagePixels)
29 return;
30
31 int32_t stride_pixels = (w + 31) & ~31;
32 if (h > kMaxImagePixels / stride_pixels)
33 return;
34
14 m_nWidth = w; 35 m_nWidth = w;
15 m_nHeight = h; 36 m_nHeight = h;
16 if (m_nWidth <= 0 || m_nHeight <= 0 || m_nWidth > INT_MAX - 31) { 37 m_nStride = stride_pixels / 8;
17 m_pData = nullptr; 38 m_pData = FX_Alloc2D(uint8_t, m_nStride, m_nHeight);
18 m_bNeedFree = FALSE; 39 }
40
41 CJBig2_Image::CJBig2_Image(int32_t w, int32_t h, int32_t stride, uint8_t* pBuf)
42 : m_pData(nullptr),
43 m_nWidth(0),
44 m_nHeight(0),
45 m_nStride(0),
46 m_bNeedFree(false) {
47 if (w < 0 || h < 0 || stride < 0 || stride > kMaxImageBytes)
19 return; 48 return;
20 } 49
21 m_nStride = ((w + 31) >> 5) << 2; 50 int32_t stride_pixels = 8 * stride;
22 if (m_nStride * m_nHeight > 0 && 104857600 / (int)m_nStride > m_nHeight) { 51 if (stride_pixels < w || h > kMaxImagePixels / stride_pixels)
23 m_pData = FX_Alloc2D(uint8_t, m_nStride, m_nHeight); 52 return;
24 } else { 53
25 m_pData = nullptr;
26 }
27 m_bNeedFree = TRUE;
28 }
29 CJBig2_Image::CJBig2_Image(int32_t w,
30 int32_t h,
31 int32_t stride,
32 uint8_t* pBuf) {
33 m_nWidth = w; 54 m_nWidth = w;
34 m_nHeight = h; 55 m_nHeight = h;
35 m_nStride = stride; 56 m_nStride = stride;
36 m_pData = pBuf; 57 m_pData = pBuf;
37 m_bNeedFree = FALSE;
38 } 58 }
39 CJBig2_Image::CJBig2_Image(const CJBig2_Image& im) { 59
40 m_nWidth = im.m_nWidth; 60 CJBig2_Image::CJBig2_Image(const CJBig2_Image& other)
41 m_nHeight = im.m_nHeight; 61 : m_pData(nullptr),
42 m_nStride = im.m_nStride; 62 m_nWidth(other.m_nWidth),
43 if (im.m_pData) { 63 m_nHeight(other.m_nHeight),
64 m_nStride(other.m_nStride),
65 m_bNeedFree(true) {
66 if (other.m_pData) {
44 m_pData = FX_Alloc2D(uint8_t, m_nStride, m_nHeight); 67 m_pData = FX_Alloc2D(uint8_t, m_nStride, m_nHeight);
45 JBIG2_memcpy(m_pData, im.m_pData, m_nStride * m_nHeight); 68 JBIG2_memcpy(m_pData, other.m_pData, m_nStride * m_nHeight);
46 } else {
47 m_pData = nullptr;
48 } 69 }
49 m_bNeedFree = TRUE;
50 } 70 }
71
51 CJBig2_Image::~CJBig2_Image() { 72 CJBig2_Image::~CJBig2_Image() {
52 if (m_bNeedFree) { 73 if (m_bNeedFree) {
53 FX_Free(m_pData); 74 FX_Free(m_pData);
54 } 75 }
55 } 76 }
56 FX_BOOL CJBig2_Image::getPixel(int32_t x, int32_t y) { 77 FX_BOOL CJBig2_Image::getPixel(int32_t x, int32_t y) {
57 if (!m_pData) { 78 if (!m_pData) {
58 return 0; 79 return 0;
59 } 80 }
60 int32_t m, n; 81 int32_t m, n;
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 pDst[1] = (uint8_t)(wTmp >> 16); 223 pDst[1] = (uint8_t)(wTmp >> 16);
203 pDst[2] = (uint8_t)(wTmp >> 8); 224 pDst[2] = (uint8_t)(wTmp >> 8);
204 pDst[3] = (uint8_t)wTmp; 225 pDst[3] = (uint8_t)wTmp;
205 } 226 }
206 pLineSrc += m_nStride; 227 pLineSrc += m_nStride;
207 pLineDst += pImage->m_nStride; 228 pLineDst += pImage->m_nStride;
208 } 229 }
209 } 230 }
210 return pImage; 231 return pImage;
211 } 232 }
233
212 void CJBig2_Image::expand(int32_t h, FX_BOOL v) { 234 void CJBig2_Image::expand(int32_t h, FX_BOOL v) {
213 if (!m_pData || h <= m_nHeight) { 235 if (!m_pData || h <= m_nHeight || h > kMaxImageBytes / m_nStride) {
214 return; 236 return;
215 } 237 }
216 uint32_t dwH = pdfium::base::checked_cast<uint32_t>(h);
217 uint32_t dwStride = pdfium::base::checked_cast<uint32_t>(m_nStride);
218 uint32_t dwHeight = pdfium::base::checked_cast<uint32_t>(m_nHeight);
219 FX_SAFE_UINT32 safeMemSize = dwH;
220 safeMemSize *= dwStride;
221 if (!safeMemSize.IsValid()) {
222 return;
223 }
224 // The guaranteed reallocated memory is to be < 4GB (unsigned int).
225 m_pData = FX_Realloc(uint8_t, m_pData, safeMemSize.ValueOrDie());
226 238
227 // The result of dwHeight * dwStride doesn't overflow after the 239 m_pData = FX_Realloc(uint8_t, m_pData, h * m_nStride);
228 // checking of safeMemSize. 240 JBIG2_memset(m_pData + m_nHeight * m_nStride, v ? 0xff : 0,
229 // The same as the result of (dwH - dwHeight) * dwStride) because 241 (h - m_nHeight) * m_nStride);
230 // dwH - dwHeight is always less than dwH(h) which is checked in
231 // the calculation of dwH * dwStride.
232 JBIG2_memset(m_pData + dwHeight * dwStride, v ? 0xff : 0,
233 (dwH - dwHeight) * dwStride);
234 m_nHeight = h; 242 m_nHeight = h;
235 } 243 }
244
236 FX_BOOL CJBig2_Image::composeTo_opt2(CJBig2_Image* pDst, 245 FX_BOOL CJBig2_Image::composeTo_opt2(CJBig2_Image* pDst,
237 int32_t x, 246 int32_t x,
238 int32_t y, 247 int32_t y,
239 JBig2ComposeOp op) { 248 JBig2ComposeOp op) {
240 int32_t xs0 = 0, ys0 = 0, xs1 = 0, ys1 = 0, xd0 = 0, yd0 = 0, xd1 = 0, 249 int32_t xs0 = 0, ys0 = 0, xs1 = 0, ys1 = 0, xd0 = 0, yd0 = 0, xd1 = 0,
241 yd1 = 0, xx = 0, yy = 0, w = 0, h = 0, middleDwords = 0, lineLeft = 0; 250 yd1 = 0, xx = 0, yy = 0, w = 0, h = 0, middleDwords = 0, lineLeft = 0;
242 251
243 uint32_t s1 = 0, d1 = 0, d2 = 0, shift = 0, shift1 = 0, shift2 = 0, tmp = 0, 252 uint32_t s1 = 0, d1 = 0, d2 = 0, shift = 0, shift1 = 0, shift2 = 0, tmp = 0,
244 tmp1 = 0, tmp2 = 0, maskL = 0, maskR = 0, maskM = 0; 253 tmp1 = 0, tmp2 = 0, maskL = 0, maskR = 0, maskM = 0;
245 254
(...skipping 828 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 dp[2] = (uint8_t)(tmp >> 8); 1083 dp[2] = (uint8_t)(tmp >> 8);
1075 dp[3] = (uint8_t)tmp; 1084 dp[3] = (uint8_t)tmp;
1076 } 1085 }
1077 lineSrc += m_nStride; 1086 lineSrc += m_nStride;
1078 lineDst += pDst->m_nStride; 1087 lineDst += pDst->m_nStride;
1079 } 1088 }
1080 } 1089 }
1081 } 1090 }
1082 return 1; 1091 return 1;
1083 } 1092 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698