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

Side by Side Diff: core/src/fxcodec/codec/fx_codec.cpp

Issue 1425983002: XFA: remove unsafe exif parsing code (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@xfa
Patch Set: Null check. Created 5 years, 1 month 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 | « core/src/fxcodec/codec/codec_int.h ('k') | core/src/fxcodec/codec/fx_codec_tiff.cpp » ('j') | 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/fxcodec/fx_codec.h" 7 #include "../../../include/fxcodec/fx_codec.h"
8 8
9 #include <cmath> 9 #include <cmath>
10 10
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 } 250 }
251 } 251 }
252 return is_negative ? -ret : ret; 252 return is_negative ? -ret : ret;
253 } 253 }
254 FX_BOOL CCodec_BasicModule::A85Encode(const uint8_t* src_buf, 254 FX_BOOL CCodec_BasicModule::A85Encode(const uint8_t* src_buf,
255 FX_DWORD src_size, 255 FX_DWORD src_size,
256 uint8_t*& dest_buf, 256 uint8_t*& dest_buf,
257 FX_DWORD& dest_size) { 257 FX_DWORD& dest_size) {
258 return FALSE; 258 return FALSE;
259 } 259 }
260 CFX_DIBAttribute::CFX_DIBAttribute() { 260 CFX_DIBAttribute::CFX_DIBAttribute()
261 FXSYS_memset(this, 0, sizeof(CFX_DIBAttribute)); 261 : m_nXDPI(-1),
262 m_nXDPI = -1; 262 m_nYDPI(-1),
263 m_nYDPI = -1; 263 m_fAspectRatio(-1.0f),
264 m_fAspectRatio = -1.0f; 264 m_wDPIUnit(0),
265 m_pExif = new CFX_DIBAttributeExif; 265 m_nGifLeft(0),
266 m_nGifTop(0),
267 m_pGifLocalPalette(nullptr),
268 m_nGifLocalPalNum(0),
269 m_nBmpCompressType(0) {
270 FXSYS_memset(m_strTime, 0, sizeof(m_strTime));
266 } 271 }
267 CFX_DIBAttribute::~CFX_DIBAttribute() { 272 CFX_DIBAttribute::~CFX_DIBAttribute() {
268 if (m_pExif) { 273 for (const auto& pair : m_Exif)
269 delete m_pExif; 274 FX_Free(pair.second);
270 }
271 } 275 }
272 CFX_DIBAttributeExif::CFX_DIBAttributeExif() { 276
273 m_pExifData = NULL;
274 m_dwExifDataLen = 0;
275 }
276 CFX_DIBAttributeExif::~CFX_DIBAttributeExif() {
277 clear();
278 }
279 void CFX_DIBAttributeExif::clear() {
280 if (m_pExifData) {
281 FX_Free(m_pExifData);
282 }
283 m_pExifData = NULL;
284 FX_DWORD key = 0;
285 uint8_t* buf = NULL;
286 FX_POSITION pos = NULL;
287 pos = m_TagHead.GetStartPosition();
288 while (pos) {
289 m_TagHead.GetNextAssoc(pos, key, buf);
290 if (buf) {
291 FX_Free(buf);
292 }
293 }
294 m_TagHead.RemoveAll();
295 pos = m_TagVal.GetStartPosition();
296 while (pos) {
297 m_TagVal.GetNextAssoc(pos, key, buf);
298 if (buf) {
299 FX_Free(buf);
300 }
301 }
302 m_TagVal.RemoveAll();
303 }
304 static FX_WORD _Read2BytesL(uint8_t* data) {
305 ASSERT(data);
306 return data[0] | (data[1] << 8);
307 }
308 static FX_WORD _Read2BytesB(uint8_t* data) {
309 ASSERT(data);
310 return data[1] | (data[0] << 8);
311 }
312 static FX_DWORD _Read4BytesL(uint8_t* data) {
313 return _Read2BytesL(data) | (_Read2BytesL(data + 2) << 16);
314 }
315 static FX_DWORD _Read4BytesB(uint8_t* data) {
316 return _Read2BytesB(data + 2) | (_Read2BytesB(data) << 16);
317 }
318 typedef FX_WORD (*_Read2Bytes)(uint8_t* data);
319 typedef FX_DWORD (*_Read4Bytes)(uint8_t* data);
320 typedef void (*_Write2Bytes)(uint8_t* data, FX_WORD val);
321 typedef void (*_Write4Bytes)(uint8_t* data, FX_DWORD val);
322 uint8_t* CFX_DIBAttributeExif::ParseExifIFH(uint8_t* data,
323 FX_DWORD len,
324 _Read2Bytes* pReadWord,
325 _Read4Bytes* pReadDword) {
326 if (len > 8) {
327 FX_BOOL tag = FALSE;
328 if (FXSYS_memcmp(data, "\x49\x49\x2a\x00", 4) == 0) {
329 if (pReadWord) {
330 *pReadWord = _Read2BytesL;
331 }
332 if (pReadDword) {
333 *pReadDword = _Read4BytesL;
334 }
335 tag = TRUE;
336 } else if (FXSYS_memcmp(data, "\x4d\x4d\x00\x2a", 4) == 0) {
337 if (pReadWord) {
338 *pReadWord = _Read2BytesB;
339 }
340 if (pReadDword) {
341 *pReadDword = _Read4BytesB;
342 }
343 tag = TRUE;
344 }
345 if (tag) {
346 data += 4;
347 if (pReadDword) {
348 data += (*pReadDword)(data)-4;
349 } else {
350 data += 4;
351 }
352 }
353 }
354 return data;
355 }
356 FX_BOOL CFX_DIBAttributeExif::ParseExifIFD(
357 CFX_MapPtrTemplate<FX_DWORD, uint8_t*>* pMap,
358 uint8_t* data,
359 FX_DWORD len) {
360 if (pMap && data) {
361 if (len > 8) {
362 FX_WORD wTagNum = m_readWord(data);
363 data += 2;
364 FX_DWORD wTag;
365 uint8_t* buf;
366 while (wTagNum--) {
367 wTag = m_readWord(data);
368 data += 2;
369 if (!pMap->Lookup(wTag, buf)) {
370 buf = FX_Alloc(uint8_t, 10);
371 if (buf == NULL) {
372 return FALSE;
373 }
374 FXSYS_memcpy(buf, data, 10);
375 pMap->SetAt(wTag, buf);
376 }
377 data += 10;
378 }
379 FX_DWORD dwIFDOffset;
380 dwIFDOffset = m_readDword(data);
381 while (dwIFDOffset && dwIFDOffset < len) {
382 data = m_pExifData + dwIFDOffset;
383 wTagNum = m_readWord(data);
384 data += 2;
385 while (wTagNum--) {
386 wTag = m_readWord(data);
387 data += 2;
388 if (!pMap->Lookup(wTag, buf)) {
389 buf = FX_Alloc(uint8_t, 10);
390 if (buf == NULL) {
391 return FALSE;
392 }
393 FXSYS_memcpy(buf, data, 10);
394 pMap->SetAt(wTag, buf);
395 }
396 data += 10;
397 }
398 dwIFDOffset = m_readDword(data);
399 }
400 return TRUE;
401 }
402 }
403 return FALSE;
404 }
405 enum FX_ExifDataType {
406 FX_UnsignedByte = 1,
407 FX_AscString,
408 FX_UnsignedShort,
409 FX_UnsignedLong,
410 FX_UnsignedRation,
411 FX_SignedByte,
412 FX_Undefined,
413 FX_SignedShort,
414 FX_SignedLong,
415 FX_SignedRation,
416 FX_SignedFloat,
417 FX_DoubleFloat
418 };
419 FX_BOOL CFX_DIBAttributeExif::ParseExif(
420 CFX_MapPtrTemplate<FX_DWORD, uint8_t*>* pHead,
421 uint8_t* data,
422 FX_DWORD len,
423 CFX_MapPtrTemplate<FX_DWORD, uint8_t*>* pVal) {
424 if (pHead && data && pVal) {
425 if (len > 8) {
426 uint8_t* old_data = data;
427 data = ParseExifIFH(data, len, &m_readWord, &m_readDword);
428 if (data == old_data) {
429 return FALSE;
430 }
431 if (pHead->GetCount() == 0) {
432 if (!ParseExifIFD(pHead, data, len)) {
433 return FALSE;
434 }
435 }
436 FX_DWORD dwModuleNum;
437 FX_WORD type;
438 FX_DWORD dwSize;
439 FX_DWORD tag;
440 uint8_t* head;
441 FX_POSITION pos = pHead->GetStartPosition();
442 while (pos) {
443 pHead->GetNextAssoc(pos, tag, head);
444 uint8_t* val = NULL;
445 uint8_t* buf = NULL;
446 uint8_t* temp = NULL;
447 int i;
448 if (head) {
449 type = m_readWord(head);
450 head += 2;
451 dwModuleNum = m_readDword(head);
452 head += 4;
453 switch (type) {
454 case FX_UnsignedByte:
455 case FX_AscString:
456 case FX_SignedByte:
457 case FX_Undefined:
458 dwSize = dwModuleNum;
459 val = FX_Alloc(uint8_t, dwSize);
460 if (val == NULL) {
461 return FALSE;
462 }
463 if (dwSize > 4) {
464 FXSYS_memcpy(val, old_data + m_readDword(head), dwSize);
465 } else {
466 FXSYS_memcpy(val, head, dwSize);
467 }
468 break;
469 case FX_UnsignedShort:
470 case FX_SignedShort:
471 dwSize = dwModuleNum << 1;
472 val = FX_Alloc(uint8_t, dwSize);
473 if (val == NULL) {
474 return FALSE;
475 }
476 if (dwSize > 4) {
477 FXSYS_memcpy(val, old_data + m_readDword(head), dwSize);
478 } else {
479 FXSYS_memcpy(val, head, dwSize);
480 }
481 buf = val;
482 for (i = 0; i < (int)dwModuleNum; i++) {
483 *(FX_WORD*)buf = m_readWord(buf);
484 buf += 2;
485 }
486 break;
487 case FX_UnsignedLong:
488 case FX_SignedLong:
489 case FX_SignedFloat:
490 dwSize = dwModuleNum << 2;
491 val = FX_Alloc(uint8_t, dwSize);
492 if (val == NULL) {
493 return FALSE;
494 }
495 if (dwSize > 4) {
496 FXSYS_memcpy(val, old_data + m_readDword(head), dwSize);
497 } else {
498 FXSYS_memcpy(val, head, dwSize);
499 }
500 buf = val;
501 for (i = 0; i < (int)dwModuleNum; i++) {
502 *(FX_DWORD*)buf = m_readDword(buf);
503 buf += 4;
504 }
505 break;
506 case FX_UnsignedRation:
507 case FX_SignedRation: {
508 dwSize = dwModuleNum << 3;
509 buf = FX_Alloc(uint8_t, dwSize);
510 if (buf == NULL) {
511 return FALSE;
512 }
513 if (dwSize > 4) {
514 FXSYS_memcpy(buf, old_data + m_readDword(head), dwSize);
515 } else {
516 FXSYS_memcpy(buf, head, dwSize);
517 }
518 temp = buf;
519 val = FX_Alloc(uint8_t, dwSize / 2);
520 if (val == NULL) {
521 FX_Free(buf);
522 return FALSE;
523 }
524 for (i = 0; i < (int)dwModuleNum; i++) {
525 *(FX_DWORD*)temp = m_readDword(temp);
526 *(FX_DWORD*)(temp + 4) = m_readDword(temp + 4);
527 FX_DWORD* lNumerator = (FX_DWORD*)temp;
528 FX_DWORD* lNenominator = (FX_DWORD*)(temp + 4);
529 *(FX_FLOAT*)(val + i * 4) =
530 (FX_FLOAT)(*lNumerator) / (FX_FLOAT)(*lNenominator);
531 temp += 8;
532 }
533 FX_Free(buf);
534 } break;
535 case FX_DoubleFloat:
536 dwSize = dwModuleNum << 3;
537 val = FX_Alloc(uint8_t, dwSize);
538 if (val == NULL) {
539 return FALSE;
540 }
541 if (dwSize > 4) {
542 FXSYS_memcpy(val, old_data + m_readDword(head), dwSize);
543 } else {
544 FXSYS_memcpy(val, head, dwSize);
545 }
546 buf = val;
547 for (i = 0; i < (int)dwModuleNum; i++) {
548 *(FX_DWORD*)buf = m_readDword(buf);
549 *(FX_DWORD*)(buf + 4) = m_readDword(buf + 4);
550 buf += 8;
551 }
552 break;
553 default:
554 return FALSE;
555 }
556 }
557 pVal->SetAt(tag, val);
558 }
559 return TRUE;
560 }
561 }
562 return FALSE;
563 }
564 #define FXEXIF_INFOCONVERT(T) \
565 { \
566 T* src = (T*)ptr; \
567 T* dst = (T*)val; \
568 *dst = *src; \
569 }
570 FX_BOOL CFX_DIBAttributeExif::GetInfo(FX_WORD tag, void* val) {
571 if (m_TagVal.GetCount() == 0) {
572 if (!ParseExif(&m_TagHead, m_pExifData, m_dwExifDataLen, &m_TagVal)) {
573 return FALSE;
574 }
575 }
576 uint8_t* ptr = NULL;
577 if (m_TagVal.Lookup(tag, ptr)) {
578 switch (tag) {
579 case EXIFTAG_USHORT_RESUNIT:
580 FXEXIF_INFOCONVERT(FX_WORD);
581 {
582 FX_WORD* ptr = (FX_WORD*)val;
583 *ptr -= 1;
584 }
585 break;
586 case EXIFTAG_FLOAT_DPIX:
587 case EXIFTAG_FLOAT_DPIY:
588 FXEXIF_INFOCONVERT(FX_FLOAT);
589 break;
590 case EXIFTAG_USHORT_ORIENTATION:
591 FXEXIF_INFOCONVERT(FX_WORD);
592 break;
593 default: {
594 uint8_t** dst = (uint8_t**)val;
595 *dst = ptr;
596 }
597 }
598 }
599 return TRUE;
600 }
601 class CCodec_RLScanlineDecoder : public CCodec_ScanlineDecoder { 277 class CCodec_RLScanlineDecoder : public CCodec_ScanlineDecoder {
602 public: 278 public:
603 CCodec_RLScanlineDecoder(); 279 CCodec_RLScanlineDecoder();
604 ~CCodec_RLScanlineDecoder() override; 280 ~CCodec_RLScanlineDecoder() override;
605 281
606 FX_BOOL Create(const uint8_t* src_buf, 282 FX_BOOL Create(const uint8_t* src_buf,
607 FX_DWORD src_size, 283 FX_DWORD src_size,
608 int width, 284 int width,
609 int height, 285 int height,
610 int nComps, 286 int nComps,
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
784 int nComps, 460 int nComps,
785 int bpc) { 461 int bpc) {
786 CCodec_RLScanlineDecoder* pRLScanlineDecoder = new CCodec_RLScanlineDecoder; 462 CCodec_RLScanlineDecoder* pRLScanlineDecoder = new CCodec_RLScanlineDecoder;
787 if (!pRLScanlineDecoder->Create(src_buf, src_size, width, height, nComps, 463 if (!pRLScanlineDecoder->Create(src_buf, src_size, width, height, nComps,
788 bpc)) { 464 bpc)) {
789 delete pRLScanlineDecoder; 465 delete pRLScanlineDecoder;
790 return NULL; 466 return NULL;
791 } 467 }
792 return pRLScanlineDecoder; 468 return pRLScanlineDecoder;
793 } 469 }
OLDNEW
« no previous file with comments | « core/src/fxcodec/codec/codec_int.h ('k') | core/src/fxcodec/codec/fx_codec_tiff.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698