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

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

Issue 1153633009: Fix potentially massive memory leak in CPDF_DIBSource::LoadJpxBitmap(). (Closed) Base URL: https://pdfium.googlesource.com/pdfium@master
Patch Set: nits Created 5 years, 6 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 "../../../../third_party/base/nonstd_unique_ptr.h"
7 #include "../../../include/fpdfapi/fpdf_module.h" 8 #include "../../../include/fpdfapi/fpdf_module.h"
8 #include "../../../include/fpdfapi/fpdf_pageobj.h" 9 #include "../../../include/fpdfapi/fpdf_pageobj.h"
9 #include "../../../include/fpdfapi/fpdf_render.h" 10 #include "../../../include/fpdfapi/fpdf_render.h"
10 #include "../../../include/fxcodec/fx_codec.h" 11 #include "../../../include/fxcodec/fx_codec.h"
11 #include "../../../include/fxcrt/fx_safe_types.h" 12 #include "../../../include/fxcrt/fx_safe_types.h"
12 #include "../../../include/fxge/fx_ge.h" 13 #include "../../../include/fxge/fx_ge.h"
13 #include "../fpdf_page/pageint.h" 14 #include "../fpdf_page/pageint.h"
14 #include "render_int.h" 15 #include "render_int.h"
15 16
16 namespace { 17 namespace {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 49
49 FX_SAFE_DWORD CalculatePitch32(int bpp, int width) 50 FX_SAFE_DWORD CalculatePitch32(int bpp, int width)
50 { 51 {
51 FX_SAFE_DWORD pitch = bpp; 52 FX_SAFE_DWORD pitch = bpp;
52 pitch *= width; 53 pitch *= width;
53 pitch += 31; 54 pitch += 31;
54 pitch /= 8; 55 pitch /= 8;
55 return pitch; 56 return pitch;
56 } 57 }
57 58
59 // Wrapper class to hold objects allocated in CPDF_DIBSource::LoadJpxBitmap(),
60 // because nonstd::unique_ptr does not support custom deleters yet.
61 class JpxBitMapContext
62 {
63 public:
64 explicit JpxBitMapContext(ICodec_JpxModule* jpx_module)
65 : jpx_module_(jpx_module),
66 ctx_(nullptr),
67 output_offsets_(nullptr) {}
68
69 ~JpxBitMapContext() {
70 FX_Free(output_offsets_);
71 jpx_module_->DestroyDecoder(ctx_);
72 }
73
74 // Takes ownership of |ctx|.
75 void set_context(void* ctx) {
76 ctx_ = ctx;
77 }
78
79 void* context() {
80 return ctx_;
81 }
82
83 // Takes ownership of |output_offsets|.
84 void set_output_offsets(FX_LPBYTE output_offsets) {
Tom Sepez 2015/06/06 19:05:04 nit: prefer void* to LPBYTE in new code.
Lei Zhang 2015/06/08 19:35:20 LPBYTE is unsigned char*.
85 output_offsets_ = output_offsets;
86 }
87
88 FX_LPBYTE output_offsets() {
89 return output_offsets_;
90 }
91
92 private:
93 ICodec_JpxModule* jpx_module_; // Weak pointer.
94 void* ctx_; // Decoder context, owned.
95 FX_LPBYTE output_offsets_; // Output offets for decoding, owned.
96
97 // Disallow evil constructors
98 JpxBitMapContext(const JpxBitMapContext&);
99 void operator=(const JpxBitMapContext&);
100 };
101
58 } // namespace 102 } // namespace
59 103
60 CFX_DIBSource* CPDF_Image::LoadDIBSource(CFX_DIBSource** ppMask, FX_DWORD* pMatt eColor, FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask) const 104 CFX_DIBSource* CPDF_Image::LoadDIBSource(CFX_DIBSource** ppMask, FX_DWORD* pMatt eColor, FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask) const
61 { 105 {
62 CPDF_DIBSource* pSource = new CPDF_DIBSource; 106 CPDF_DIBSource* pSource = new CPDF_DIBSource;
63 if (pSource->Load(m_pDocument, m_pStream, (CPDF_DIBSource**)ppMask, pMatteCo lor, NULL, NULL, bStdCS, GroupFamily, bLoadMask)) { 107 if (pSource->Load(m_pDocument, m_pStream, (CPDF_DIBSource**)ppMask, pMatteCo lor, NULL, NULL, bStdCS, GroupFamily, bLoadMask)) {
64 return pSource; 108 return pSource;
65 } 109 }
66 delete pSource; 110 delete pSource;
67 return NULL; 111 return NULL;
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 return 0; 666 return 0;
623 } 667 }
624 if (provided_pitch.ValueOrDie() < requested_pitch.ValueOrDie()) { 668 if (provided_pitch.ValueOrDie() < requested_pitch.ValueOrDie()) {
625 return 0; 669 return 0;
626 } 670 }
627 return 1; 671 return 1;
628 } 672 }
629 void CPDF_DIBSource::LoadJpxBitmap() 673 void CPDF_DIBSource::LoadJpxBitmap()
630 { 674 {
631 ICodec_JpxModule* pJpxModule = CPDF_ModuleMgr::Get()->GetJpxModule(); 675 ICodec_JpxModule* pJpxModule = CPDF_ModuleMgr::Get()->GetJpxModule();
632 if (pJpxModule == NULL) { 676 if (!pJpxModule)
633 return; 677 return;
634 } 678
635 FX_LPVOID ctx = pJpxModule->CreateDecoder(m_pStreamAcc->GetData(), m_pStream Acc->GetSize(), m_pColorSpace != NULL); 679 nonstd::unique_ptr<JpxBitMapContext> context(
636 if (ctx == NULL) { 680 new JpxBitMapContext(pJpxModule));
681 context->set_context(pJpxModule->CreateDecoder(m_pStreamAcc->GetData(),
682 m_pStreamAcc->GetSize(),
683 m_pColorSpace != nullptr));
684 if (!context->context())
637 return; 685 return;
638 } 686
639 FX_DWORD width = 0, height = 0, codestream_nComps = 0, image_nComps = 0; 687 FX_DWORD width = 0;
640 pJpxModule->GetImageInfo(ctx, width, height, codestream_nComps, image_nComps ); 688 FX_DWORD height = 0;
641 if ((int)width < m_Width || (int)height < m_Height) { 689 FX_DWORD codestream_nComps = 0;
642 pJpxModule->DestroyDecoder(ctx); 690 FX_DWORD image_nComps = 0;
691 pJpxModule->GetImageInfo(context->context(), width, height,
692 codestream_nComps, image_nComps);
693 if ((int)width < m_Width || (int)height < m_Height)
643 return; 694 return;
644 } 695
645 int output_nComps; 696 int output_nComps;
646 FX_BOOL bTranslateColor, bSwapRGB = FALSE; 697 FX_BOOL bTranslateColor;
698 FX_BOOL bSwapRGB = FALSE;
647 if (m_pColorSpace) { 699 if (m_pColorSpace) {
648 if (codestream_nComps != (FX_DWORD)m_pColorSpace->CountComponents()) { 700 if (codestream_nComps != (FX_DWORD)m_pColorSpace->CountComponents())
649 return; 701 return;
650 }
651 output_nComps = codestream_nComps; 702 output_nComps = codestream_nComps;
652 bTranslateColor = FALSE; 703 bTranslateColor = FALSE;
653 if (m_pColorSpace == CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB)) { 704 if (m_pColorSpace == CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB)) {
654 bSwapRGB = TRUE; 705 bSwapRGB = TRUE;
655 m_pColorSpace = NULL; 706 m_pColorSpace = nullptr;
656 } 707 }
657 } else { 708 } else {
658 bTranslateColor = TRUE; 709 bTranslateColor = TRUE;
659 if (image_nComps) { 710 if (image_nComps) {
660 output_nComps = image_nComps; 711 output_nComps = image_nComps;
661 } else { 712 } else {
662 output_nComps = codestream_nComps; 713 output_nComps = codestream_nComps;
663 } 714 }
664 if (output_nComps == 3) { 715 if (output_nComps == 3) {
665 bSwapRGB = TRUE; 716 bSwapRGB = TRUE;
(...skipping 10 matching lines...) Expand all
676 format = FXDIB_Rgb; 727 format = FXDIB_Rgb;
677 } else if (output_nComps == 4) { 728 } else if (output_nComps == 4) {
678 format = FXDIB_Rgb32; 729 format = FXDIB_Rgb32;
679 } else { 730 } else {
680 width = (width * output_nComps + 2) / 3; 731 width = (width * output_nComps + 2) / 3;
681 format = FXDIB_Rgb; 732 format = FXDIB_Rgb;
682 } 733 }
683 m_pCachedBitmap = new CFX_DIBitmap; 734 m_pCachedBitmap = new CFX_DIBitmap;
684 if (!m_pCachedBitmap->Create(width, height, format)) { 735 if (!m_pCachedBitmap->Create(width, height, format)) {
685 delete m_pCachedBitmap; 736 delete m_pCachedBitmap;
686 m_pCachedBitmap = NULL; 737 m_pCachedBitmap = nullptr;
687 return; 738 return;
688 } 739 }
689 m_pCachedBitmap->Clear(0xFFFFFFFF); 740 m_pCachedBitmap->Clear(0xFFFFFFFF);
690 FX_LPBYTE output_offsets = FX_Alloc(FX_BYTE, output_nComps); 741 context->set_output_offsets(FX_Alloc(FX_BYTE, output_nComps));
691 for (int i = 0; i < output_nComps; i ++) { 742 for (int i = 0; i < output_nComps; ++i)
692 output_offsets[i] = i; 743 context->output_offsets()[i] = i;
744 if (bSwapRGB) {
745 context->output_offsets()[0] = 2;
746 context->output_offsets()[2] = 0;
693 } 747 }
694 if (bSwapRGB) { 748 if (!pJpxModule->Decode(context->context(),
695 output_offsets[0] = 2; 749 m_pCachedBitmap->GetBuffer(),
696 output_offsets[2] = 0; 750 m_pCachedBitmap->GetPitch(),
697 } 751 bTranslateColor,
698 if (!pJpxModule->Decode(ctx, m_pCachedBitmap->GetBuffer(), m_pCachedBitmap-> GetPitch(), bTranslateColor, output_offsets)) { 752 context->output_offsets())) {
699 delete m_pCachedBitmap; 753 delete m_pCachedBitmap;
Tom Sepez 2015/06/06 19:05:04 nit: can m_pCachedBitmap be a unique_ptr?
Lei Zhang 2015/06/08 19:35:20 Done.
700 m_pCachedBitmap = NULL; 754 m_pCachedBitmap = nullptr;
701 return; 755 return;
Tom Sepez 2015/06/06 19:05:04 Nit: presumably this is the return that leaks, rig
Lei Zhang 2015/06/08 19:35:20 The failures are on line 700 above. "if (codestrea
702 } 756 }
703 FX_Free(output_offsets); 757 if (m_pColorSpace &&
704 pJpxModule->DestroyDecoder(ctx); 758 m_pColorSpace->GetFamily() == PDFCS_INDEXED &&
705 if (m_pColorSpace && m_pColorSpace->GetFamily() == PDFCS_INDEXED && m_bpc < 8) { 759 m_bpc < 8) {
706 int scale = 8 - m_bpc; 760 int scale = 8 - m_bpc;
707 for (FX_DWORD row = 0; row < height; row ++) { 761 for (FX_DWORD row = 0; row < height; ++row) {
708 FX_LPBYTE scanline = (FX_LPBYTE)m_pCachedBitmap->GetScanline(row); 762 FX_LPBYTE scanline = (FX_LPBYTE)m_pCachedBitmap->GetScanline(row);
709 for (FX_DWORD col = 0; col < width; col ++) { 763 for (FX_DWORD col = 0; col < width; ++col) {
710 *scanline = (*scanline) >> scale; 764 *scanline = (*scanline) >> scale;
711 scanline++; 765 ++scanline;
712 } 766 }
713 } 767 }
714 } 768 }
715 m_bpc = 8; 769 m_bpc = 8;
716 } 770 }
717 CPDF_DIBSource* CPDF_DIBSource::LoadMask(FX_DWORD& MatteColor) 771 CPDF_DIBSource* CPDF_DIBSource::LoadMask(FX_DWORD& MatteColor)
718 { 772 {
719 MatteColor = 0xffffffff; 773 MatteColor = 0xffffffff;
720 CPDF_Stream* pSoftMask = m_pDict->GetStream(FX_BSTRC("SMask")); 774 CPDF_Stream* pSoftMask = m_pDict->GetStream(FX_BSTRC("SMask"));
721 if (pSoftMask) { 775 if (pSoftMask) {
(...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after
1504 { 1558 {
1505 return ((CPDF_ProgressiveImageLoaderHandle*)LoadHandle)->Continue(pPause); 1559 return ((CPDF_ProgressiveImageLoaderHandle*)LoadHandle)->Continue(pPause);
1506 } 1560 }
1507 CPDF_ImageLoader::~CPDF_ImageLoader() 1561 CPDF_ImageLoader::~CPDF_ImageLoader()
1508 { 1562 {
1509 if (!m_bCached) { 1563 if (!m_bCached) {
1510 delete m_pBitmap; 1564 delete m_pBitmap;
1511 delete m_pMask; 1565 delete m_pMask;
1512 } 1566 }
1513 } 1567 }
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