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

Side by Side Diff: core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp

Issue 419693003: Fix potential integer overflow in fpdf_render_loadimage.cpp (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Created 6 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "../../../include/fxge/fx_ge.h" 7 #include "../../../include/fxge/fx_ge.h"
8 #include "../../../include/fxcodec/fx_codec.h" 8 #include "../../../include/fxcodec/fx_codec.h"
9 #include "../../../include/fpdfapi/fpdf_module.h" 9 #include "../../../include/fpdfapi/fpdf_module.h"
10 #include "../../../include/fpdfapi/fpdf_render.h" 10 #include "../../../include/fpdfapi/fpdf_render.h"
11 #include "../../../include/fpdfapi/fpdf_pageobj.h" 11 #include "../../../include/fpdfapi/fpdf_pageobj.h"
12 #include "../fpdf_page/pageint.h" 12 #include "../fpdf_page/pageint.h"
13 #include "render_int.h" 13 #include "render_int.h"
14 #include <limits.h> 14 #include "../../../../third_party/numerics/safe_math.h"
15
15 static unsigned int _GetBits8(FX_LPCBYTE pData, int bitpos, int nbits) 16 static unsigned int _GetBits8(FX_LPCBYTE pData, int bitpos, int nbits)
16 { 17 {
17 unsigned int byte = pData[bitpos / 8]; 18 unsigned int byte = pData[bitpos / 8];
18 if (nbits == 8) { 19 if (nbits == 8) {
19 return byte; 20 return byte;
20 } else if (nbits == 4) { 21 } else if (nbits == 4) {
21 return (bitpos % 8) ? (byte & 0x0f) : (byte >> 4); 22 return (bitpos % 8) ? (byte & 0x0f) : (byte >> 4);
22 } else if (nbits == 2) { 23 } else if (nbits == 2) {
23 return (byte >> (6 - bitpos % 8)) & 0x03; 24 return (byte >> (6 - bitpos % 8)) & 0x03;
24 } else if (nbits == 1) { 25 } else if (nbits == 1) {
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 m_Width = m_pDict->GetInteger(FX_BSTRC("Width")); 169 m_Width = m_pDict->GetInteger(FX_BSTRC("Width"));
169 m_Height = m_pDict->GetInteger(FX_BSTRC("Height")); 170 m_Height = m_pDict->GetInteger(FX_BSTRC("Height"));
170 if (m_Width <= 0 || m_Height <= 0 || m_Width > 0x01ffff || m_Height > 0x01ff ff) { 171 if (m_Width <= 0 || m_Height <= 0 || m_Width > 0x01ffff || m_Height > 0x01ff ff) {
171 return FALSE; 172 return FALSE;
172 } 173 }
173 m_GroupFamily = GroupFamily; 174 m_GroupFamily = GroupFamily;
174 m_bLoadMask = bLoadMask; 175 m_bLoadMask = bLoadMask;
175 if (!LoadColorInfo(m_pStream->GetObjNum() != 0 ? NULL : pFormResources, pPag eResources)) { 176 if (!LoadColorInfo(m_pStream->GetObjNum() != 0 ? NULL : pFormResources, pPag eResources)) {
176 return FALSE; 177 return FALSE;
177 } 178 }
178 FX_DWORD src_pitch = m_bpc; 179
179 if (m_bpc != 0 && m_nComponents != 0) { 180 if (m_bpc == 0 || m_nComponents == 0) {
180 if (src_pitch > 0 && m_nComponents > (unsigned)INT_MAX / src_pitch) { 181 return FALSE;
181 return FALSE;
182 }
183 src_pitch *= m_nComponents;
184 if (src_pitch > 0 && (FX_DWORD)m_Width > (unsigned)INT_MAX / src_pitch) {
185 return FALSE;
186 }
187 src_pitch *= m_Width;
188 if (src_pitch + 7 < src_pitch) {
189 return FALSE;
190 }
191 src_pitch += 7;
192 src_pitch /= 8;
193 if (src_pitch > 0 && (FX_DWORD)m_Height > (unsigned)INT_MAX / src_pitch) {
194 return FALSE;
195 }
196 } 182 }
183
184 FX_SAFE_DWORD src_pitch = m_bpc;
185 src_pitch *= m_nComponents;
186 src_pitch *= m_Width;
187 src_pitch += 7;
188 src_pitch /= 8;
189 src_pitch *= m_Height;
190 if (!src_pitch.IsValid()) {
191 return FALSE;
192 }
193
197 m_pStreamAcc = FX_NEW CPDF_StreamAcc; 194 m_pStreamAcc = FX_NEW CPDF_StreamAcc;
198 m_pStreamAcc->LoadAllData(pStream, FALSE, m_Height * src_pitch, TRUE); 195 m_pStreamAcc->LoadAllData(pStream, FALSE, src_pitch.ValueOrDie(), TRUE);
199 if (m_pStreamAcc->GetSize() == 0 || m_pStreamAcc->GetData() == NULL) { 196 if (m_pStreamAcc->GetSize() == 0 || m_pStreamAcc->GetData() == NULL) {
200 return FALSE; 197 return FALSE;
201 } 198 }
202 const CFX_ByteString& decoder = m_pStreamAcc->GetImageDecoder(); 199 const CFX_ByteString& decoder = m_pStreamAcc->GetImageDecoder();
203 if (!decoder.IsEmpty() && decoder == FX_BSTRC("CCITTFaxDecode")) { 200 if (!decoder.IsEmpty() && decoder == FX_BSTRC("CCITTFaxDecode")) {
204 m_bpc = 1; 201 m_bpc = 1;
205 } 202 }
206 if (!CreateDecoder()) { 203 if (!CreateDecoder()) {
207 return FALSE; 204 return FALSE;
208 } 205 }
209 if (m_bImageMask) { 206 if (m_bImageMask) {
210 m_bpp = 1; 207 m_bpp = 1;
211 m_bpc = 1; 208 m_bpc = 1;
212 m_nComponents = 1; 209 m_nComponents = 1;
213 m_AlphaFlag = 1; 210 m_AlphaFlag = 1;
214 } else if (m_bpc * m_nComponents == 1) { 211 } else if (m_bpc * m_nComponents == 1) {
215 m_bpp = 1; 212 m_bpp = 1;
216 } else if (m_bpc * m_nComponents <= 8) { 213 } else if (m_bpc * m_nComponents <= 8) {
217 m_bpp = 8; 214 m_bpp = 8;
218 } else { 215 } else {
219 m_bpp = 24; 216 m_bpp = 24;
220 } 217 }
221 if (!m_bpc || !m_nComponents) { 218
219 FX_SAFE_DWORD pitch = m_Width;
220 pitch *= m_bpp;
221 pitch += 31;
222 pitch /= 8;
223 if (!pitch.IsValid()) {
222 return FALSE; 224 return FALSE;
223 } 225 }
224 m_Pitch = m_Width; 226
225 if ((FX_DWORD)m_bpp > (unsigned)INT_MAX / m_Pitch) { 227 m_pLineBuf = FX_Alloc(FX_BYTE, pitch.ValueOrDie());
226 return FALSE;
227 }
228 m_Pitch *= m_bpp;
229 if (m_Pitch + 31 < m_Pitch) {
230 return FALSE;
231 }
232 m_Pitch += 31;
233 m_Pitch = m_Pitch / 32 * 4;
234 m_pLineBuf = FX_Alloc(FX_BYTE, m_Pitch);
235 if (m_pColorSpace && bStdCS) { 228 if (m_pColorSpace && bStdCS) {
236 m_pColorSpace->EnableStdConversion(TRUE); 229 m_pColorSpace->EnableStdConversion(TRUE);
237 } 230 }
238 LoadPalette(); 231 LoadPalette();
239 if (m_bColorKey) { 232 if (m_bColorKey) {
240 m_bpp = 32; 233 m_bpp = 32;
241 m_AlphaFlag = 2; 234 m_AlphaFlag = 2;
242 m_Pitch = m_Width; 235 pitch = m_Width;
243 if ((FX_DWORD)m_bpp > (unsigned)INT_MAX / m_Pitch) { 236 pitch *= m_bpp;
237 pitch += 31;
238 pitch /= 8;
239 if (!pitch.IsValid()) {
244 return FALSE; 240 return FALSE;
245 } 241 }
246 m_Pitch *= m_bpp; 242
247 if (m_Pitch + 31 < m_Pitch) { 243 m_pMaskedLine = FX_Alloc(FX_BYTE, pitch.ValueOrDie());
248 return FALSE;
249 }
250 m_Pitch += 31;
251 m_Pitch = m_Pitch / 32 * 4;
252 m_pMaskedLine = FX_Alloc(FX_BYTE, m_Pitch);
253 } 244 }
245 m_Pitch = pitch.ValueOrDie();
254 if (ppMask) { 246 if (ppMask) {
255 *ppMask = LoadMask(*pMatteColor); 247 *ppMask = LoadMask(*pMatteColor);
256 } 248 }
257 if (m_pColorSpace && bStdCS) { 249 if (m_pColorSpace && bStdCS) {
258 m_pColorSpace->EnableStdConversion(FALSE); 250 m_pColorSpace->EnableStdConversion(FALSE);
259 } 251 }
260 return TRUE; 252 return TRUE;
261 } 253 }
262 int CPDF_DIBSource::ContinueToLoadMask() 254 int CPDF_DIBSource::ContinueToLoadMask()
263 { 255 {
264 if (m_bImageMask) { 256 if (m_bImageMask) {
265 m_bpp = 1; 257 m_bpp = 1;
266 m_bpc = 1; 258 m_bpc = 1;
267 m_nComponents = 1; 259 m_nComponents = 1;
268 m_AlphaFlag = 1; 260 m_AlphaFlag = 1;
269 } else if (m_bpc * m_nComponents == 1) { 261 } else if (m_bpc * m_nComponents == 1) {
270 m_bpp = 1; 262 m_bpp = 1;
271 } else if (m_bpc * m_nComponents <= 8) { 263 } else if (m_bpc * m_nComponents <= 8) {
272 m_bpp = 8; 264 m_bpp = 8;
273 } else { 265 } else {
274 m_bpp = 24; 266 m_bpp = 24;
275 } 267 }
276 if (!m_bpc || !m_nComponents) { 268 if (!m_bpc || !m_nComponents) {
277 return 0; 269 return 0;
278 } 270 }
279 m_Pitch = m_Width; 271 FX_SAFE_DWORD pitch = m_Width;
280 if ((FX_DWORD)m_bpp > (unsigned)INT_MAX / m_Pitch) { 272 pitch *= m_bpp;
273 pitch += 31;
274 pitch /= 8;
275 if (!pitch.IsValid()) {
281 return 0; 276 return 0;
282 } 277 }
283 m_Pitch *= m_bpp; 278 m_pLineBuf = FX_Alloc(FX_BYTE, pitch.ValueOrDie());
284 if (m_Pitch + 31 < m_Pitch) {
285 return 0;
286 }
287 m_Pitch += 31;
288 m_Pitch = m_Pitch / 32 * 4;
289 m_pLineBuf = FX_Alloc(FX_BYTE, m_Pitch);
290 if (m_pColorSpace && m_bStdCS) { 279 if (m_pColorSpace && m_bStdCS) {
291 m_pColorSpace->EnableStdConversion(TRUE); 280 m_pColorSpace->EnableStdConversion(TRUE);
292 } 281 }
293 LoadPalette(); 282 LoadPalette();
294 if (m_bColorKey) { 283 if (m_bColorKey) {
295 m_bpp = 32; 284 m_bpp = 32;
296 m_AlphaFlag = 2; 285 m_AlphaFlag = 2;
297 m_Pitch = m_Width; 286 pitch = m_Width;
298 if ((FX_DWORD)m_bpp > (unsigned)INT_MAX / m_Pitch) { 287 pitch *= m_bpp;
288 pitch += 31;
289 pitch /= 8;
290 if (!pitch.IsValid()) {
299 return 0; 291 return 0;
300 } 292 }
301 m_Pitch *= m_bpp; 293 m_pMaskedLine = FX_Alloc(FX_BYTE, pitch.ValueOrDie());
302 if (m_Pitch + 31 < m_Pitch) {
303 return 0;
304 }
305 m_Pitch += 31;
306 m_Pitch = m_Pitch / 32 * 4;
307 m_pMaskedLine = FX_Alloc(FX_BYTE, m_Pitch);
308 } 294 }
295 m_Pitch = pitch.ValueOrDie();
309 return 1; 296 return 1;
310 } 297 }
311 int CPDF_DIBSource::StartLoadDIBSource(CPDF_Document* pDoc, const CPDF_Strea m* pStream, FX_BOOL bHasMask, 298 int CPDF_DIBSource::StartLoadDIBSource(CPDF_Document* pDoc, const CPDF_Strea m* pStream, FX_BOOL bHasMask,
312 CPDF_Dictionary* pFormResources, CPDF_Dic tionary* pPageResources, 299 CPDF_Dictionary* pFormResources, CPDF_Dic tionary* pPageResources,
313 FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_ BOOL bLoadMask) 300 FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_ BOOL bLoadMask)
314 { 301 {
315 if (pStream == NULL) { 302 if (pStream == NULL) {
316 return 0; 303 return 0;
317 } 304 }
318 m_pDocument = pDoc; 305 m_pDocument = pDoc;
319 m_pDict = pStream->GetDict(); 306 m_pDict = pStream->GetDict();
320 m_pStream = pStream; 307 m_pStream = pStream;
321 m_bStdCS = bStdCS; 308 m_bStdCS = bStdCS;
322 m_bHasMask = bHasMask; 309 m_bHasMask = bHasMask;
323 m_Width = m_pDict->GetInteger(FX_BSTRC("Width")); 310 m_Width = m_pDict->GetInteger(FX_BSTRC("Width"));
324 m_Height = m_pDict->GetInteger(FX_BSTRC("Height")); 311 m_Height = m_pDict->GetInteger(FX_BSTRC("Height"));
325 if (m_Width <= 0 || m_Height <= 0 || m_Width > 0x01ffff || m_Height > 0x01ff ff) { 312 if (m_Width <= 0 || m_Height <= 0 || m_Width > 0x01ffff || m_Height > 0x01ff ff) {
326 return 0; 313 return 0;
327 } 314 }
328 m_GroupFamily = GroupFamily; 315 m_GroupFamily = GroupFamily;
329 m_bLoadMask = bLoadMask; 316 m_bLoadMask = bLoadMask;
330 if (!LoadColorInfo(m_pStream->GetObjNum() != 0 ? NULL : pFormResources, pPag eResources)) { 317 if (!LoadColorInfo(m_pStream->GetObjNum() != 0 ? NULL : pFormResources, pPag eResources)) {
331 return 0; 318 return 0;
332 } 319 }
333 FX_DWORD src_pitch = m_bpc; 320
334 if (m_bpc != 0 && m_nComponents != 0) { 321 if (m_bpc == 0 || m_nComponents == 0) {
335 if (src_pitch > 0 && m_nComponents > (unsigned)INT_MAX / src_pitch) { 322 return 0;
336 return 0;
337 }
338 src_pitch *= m_nComponents;
339 if (src_pitch > 0 && (FX_DWORD)m_Width > (unsigned)INT_MAX / src_pitch) {
340 return 0;
341 }
342 src_pitch *= m_Width;
343 if (src_pitch + 7 < src_pitch) {
344 return 0;
345 }
346 src_pitch += 7;
347 src_pitch /= 8;
348 if (src_pitch > 0 && (FX_DWORD)m_Height > (unsigned)INT_MAX / src_pitch) {
349 return 0;
350 }
351 } 323 }
324
325 FX_SAFE_DWORD src_pitch = m_bpc;
326 src_pitch *= m_nComponents;
327 src_pitch *= m_Width;
328 src_pitch += 7;
329 src_pitch /= 8;
330 src_pitch *= m_Height;
331 if (!src_pitch.IsValid()) {
332 return 0;
333 }
334
352 m_pStreamAcc = FX_NEW CPDF_StreamAcc; 335 m_pStreamAcc = FX_NEW CPDF_StreamAcc;
353 m_pStreamAcc->LoadAllData(pStream, FALSE, m_Height * src_pitch, TRUE); 336 m_pStreamAcc->LoadAllData(pStream, FALSE, src_pitch.ValueOrDie(), TRUE);
354 if (m_pStreamAcc->GetSize() == 0 || m_pStreamAcc->GetData() == NULL) { 337 if (m_pStreamAcc->GetSize() == 0 || m_pStreamAcc->GetData() == NULL) {
355 return 0; 338 return 0;
356 } 339 }
357 const CFX_ByteString& decoder = m_pStreamAcc->GetImageDecoder(); 340 const CFX_ByteString& decoder = m_pStreamAcc->GetImageDecoder();
358 if (!decoder.IsEmpty() && decoder == FX_BSTRC("CCITTFaxDecode")) { 341 if (!decoder.IsEmpty() && decoder == FX_BSTRC("CCITTFaxDecode")) {
359 m_bpc = 1; 342 m_bpc = 1;
360 } 343 }
361 int ret = CreateDecoder(); 344 int ret = CreateDecoder();
362 if (ret != 1) { 345 if (ret != 1) {
363 if (!ret) { 346 if (!ret) {
(...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after
1175 FX_BOOL CPDF_DIBSource::SkipToScanline(int line, IFX_Pause* pPause) const 1158 FX_BOOL CPDF_DIBSource::SkipToScanline(int line, IFX_Pause* pPause) const
1176 { 1159 {
1177 if (m_pDecoder) { 1160 if (m_pDecoder) {
1178 return m_pDecoder->SkipToScanline(line, pPause); 1161 return m_pDecoder->SkipToScanline(line, pPause);
1179 } 1162 }
1180 return FALSE; 1163 return FALSE;
1181 } 1164 }
1182 void CPDF_DIBSource::DownSampleScanline(int line, FX_LPBYTE dest_scan, int dest_ bpp, 1165 void CPDF_DIBSource::DownSampleScanline(int line, FX_LPBYTE dest_scan, int dest_ bpp,
1183 int dest_width, FX_BOOL bFlipX, int clip _left, int clip_width) const 1166 int dest_width, FX_BOOL bFlipX, int clip _left, int clip_width) const
1184 { 1167 {
1168 if (line < 0 || dest_scan == NULL || dest_bpp <= 0 ||
1169 dest_width <= 0 || clip_left < 0 || clip_width <= 0) {
1170 return;
1171 }
1172
1185 FX_DWORD bpc = GetValidBpc(); 1173 FX_DWORD bpc = GetValidBpc();
1186 FX_DWORD src_width = m_Width; 1174 FX_DWORD src_width = m_Width;
1187 FX_DWORD src_pitch = (src_width * bpc * m_nComponents + 7) / 8; 1175 FX_SAFE_DWORD pitch = src_width;
1176 pitch *= bpc;
1177 pitch *= m_nComponents;
1178 pitch += 7;
1179 pitch /= 8;
1180 if (!pitch.IsValid()) {
1181 return;
1182 }
1183
1188 FX_LPCBYTE pSrcLine = NULL; 1184 FX_LPCBYTE pSrcLine = NULL;
1189 if (m_pCachedBitmap) { 1185 if (m_pCachedBitmap) {
1190 pSrcLine = m_pCachedBitmap->GetScanline(line); 1186 pSrcLine = m_pCachedBitmap->GetScanline(line);
1191 } else if (m_pDecoder) { 1187 } else if (m_pDecoder) {
1192 pSrcLine = m_pDecoder->GetScanline(line); 1188 pSrcLine = m_pDecoder->GetScanline(line);
1193 } else { 1189 } else {
1194 if (m_pStreamAcc->GetSize() >= (line + 1) * src_pitch) { 1190 FX_DWORD src_pitch = pitch.ValueOrDie();
1191 pitch *= (line+1);
1192 if (!pitch.IsValid()) {
1193 return;
1194 }
1195
1196 if (m_pStreamAcc->GetSize() >= pitch.ValueOrDie()) {
1195 pSrcLine = m_pStreamAcc->GetData() + line * src_pitch; 1197 pSrcLine = m_pStreamAcc->GetData() + line * src_pitch;
1196 } 1198 }
1197 } 1199 }
1198 int orig_Bpp = bpc * m_nComponents / 8; 1200 int orig_Bpp = bpc * m_nComponents / 8;
1199 int dest_Bpp = dest_bpp / 8; 1201 int dest_Bpp = dest_bpp / 8;
1200 if (pSrcLine == NULL) { 1202 if (pSrcLine == NULL) {
1201 FXSYS_memset32(dest_scan, 0xff, dest_Bpp * clip_width); 1203 FXSYS_memset32(dest_scan, 0xff, dest_Bpp * clip_width);
1202 return; 1204 return;
1203 } 1205 }
1206
1207 FX_SAFE_INT max_src_x = clip_left;
1208 max_src_x += clip_width - 1;
1209 max_src_x *= src_width;
1210 max_src_x /= dest_width;
1211 if (!max_src_x.IsValid()) {
1212 return;
1213 }
1214
1204 CFX_FixedBufGrow<FX_BYTE, 128> temp(orig_Bpp); 1215 CFX_FixedBufGrow<FX_BYTE, 128> temp(orig_Bpp);
1205 if (bpc * m_nComponents == 1) { 1216 if (bpc * m_nComponents == 1) {
1206 FX_DWORD set_argb = (FX_DWORD) - 1, reset_argb = 0; 1217 FX_DWORD set_argb = (FX_DWORD) - 1, reset_argb = 0;
1207 if (m_bImageMask) { 1218 if (m_bImageMask) {
1208 if (m_bDefaultDecode) { 1219 if (m_bDefaultDecode) {
1209 set_argb = 0; 1220 set_argb = 0;
1210 reset_argb = (FX_DWORD) - 1; 1221 reset_argb = (FX_DWORD) - 1;
1211 } 1222 }
1212 } else if (m_bColorKey) { 1223 } else if (m_bColorKey) {
1213 reset_argb = m_pPalette ? m_pPalette[0] : 0xff000000; 1224 reset_argb = m_pPalette ? m_pPalette[0] : 0xff000000;
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
1505 if (!m_bCached) { 1516 if (!m_bCached) {
1506 if (m_pBitmap) { 1517 if (m_pBitmap) {
1507 delete m_pBitmap; 1518 delete m_pBitmap;
1508 m_pBitmap = NULL; 1519 m_pBitmap = NULL;
1509 } 1520 }
1510 if (m_pMask) { 1521 if (m_pMask) {
1511 delete m_pMask; 1522 delete m_pMask;
1512 } 1523 }
1513 } 1524 }
1514 } 1525 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698