Make CCodec_ModuleMgr a per-process singleton.
Avoids some layering violatons at the cost of having global
singletons.
Change-Id: Idb23f77b657573f30406b32379268c7e81d56f35
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/55410
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/cpdf_modulemgr.cpp b/core/fpdfapi/cpdf_modulemgr.cpp
index 494b2fc..7b9f8f6 100644
--- a/core/fpdfapi/cpdf_modulemgr.cpp
+++ b/core/fpdfapi/cpdf_modulemgr.cpp
@@ -15,22 +15,6 @@
#include "core/fxcodec/fx_codec.h"
#include "third_party/base/ptr_util.h"
-#ifdef PDF_ENABLE_XFA_BMP
-#include "core/fxcodec/codec/ccodec_bmpmodule.h"
-#endif
-
-#ifdef PDF_ENABLE_XFA_GIF
-#include "core/fxcodec/codec/ccodec_gifmodule.h"
-#endif
-
-#ifdef PDF_ENABLE_XFA_PNG
-#include "core/fxcodec/codec/ccodec_pngmodule.h"
-#endif
-
-#ifdef PDF_ENABLE_XFA_TIFF
-#include "core/fxcodec/codec/ccodec_tiffmodule.h"
-#endif
-
namespace {
CPDF_ModuleMgr* g_pDefaultMgr = nullptr;
@@ -41,15 +25,15 @@
void CPDF_ModuleMgr::Create() {
ASSERT(!g_pDefaultMgr);
g_pDefaultMgr = new CPDF_ModuleMgr;
- g_pDefaultMgr->InitCodecModule();
+ CCodec_ModuleMgr::Create();
g_pDefaultMgr->InitPageModule();
g_pDefaultMgr->LoadEmbeddedMaps();
- g_pDefaultMgr->LoadCodecModules();
}
// static
void CPDF_ModuleMgr::Destroy() {
ASSERT(g_pDefaultMgr);
+ CCodec_ModuleMgr::Destroy();
delete g_pDefaultMgr;
g_pDefaultMgr = nullptr;
}
@@ -64,40 +48,10 @@
CPDF_ModuleMgr::~CPDF_ModuleMgr() = default;
-CCodec_JpegModule* CPDF_ModuleMgr::GetJpegModule() {
- return m_pCodecModule->GetJpegModule();
-}
-
-CCodec_Jbig2Module* CPDF_ModuleMgr::GetJbig2Module() {
- return m_pCodecModule->GetJbig2Module();
-}
-
void CPDF_ModuleMgr::InitPageModule() {
m_pPageModule = pdfium::MakeUnique<CPDF_PageModule>();
}
-void CPDF_ModuleMgr::InitCodecModule() {
- m_pCodecModule = pdfium::MakeUnique<CCodec_ModuleMgr>();
-}
-
-void CPDF_ModuleMgr::LoadCodecModules() {
-#ifdef PDF_ENABLE_XFA_BMP
- m_pCodecModule->SetBmpModule(pdfium::MakeUnique<CCodec_BmpModule>());
-#endif
-
-#ifdef PDF_ENABLE_XFA_GIF
- m_pCodecModule->SetGifModule(pdfium::MakeUnique<CCodec_GifModule>());
-#endif
-
-#ifdef PDF_ENABLE_XFA_PNG
- m_pCodecModule->SetPngModule(pdfium::MakeUnique<CCodec_PngModule>());
-#endif
-
-#ifdef PDF_ENABLE_XFA_TIFF
- m_pCodecModule->SetTiffModule(pdfium::MakeUnique<CCodec_TiffModule>());
-#endif
-}
-
void CPDF_ModuleMgr::LoadEmbeddedMaps() {
LoadEmbeddedGB1CMaps();
LoadEmbeddedCNS1CMaps();
diff --git a/core/fpdfapi/cpdf_modulemgr.h b/core/fpdfapi/cpdf_modulemgr.h
index e4793a9..f768d19 100644
--- a/core/fpdfapi/cpdf_modulemgr.h
+++ b/core/fpdfapi/cpdf_modulemgr.h
@@ -10,10 +10,6 @@
#include <memory>
#include <utility>
-class CCodec_FlateModule;
-class CCodec_Jbig2Module;
-class CCodec_JpegModule;
-class CCodec_ModuleMgr;
class CPDF_PageModule;
namespace fpdfapi {
@@ -45,27 +41,19 @@
return m_pUnsupportInfoAdapter.get();
}
- CCodec_ModuleMgr* GetCodecModule() const { return m_pCodecModule.get(); }
CPDF_PageModule* GetPageModule() const { return m_pPageModule.get(); }
- CCodec_JpegModule* GetJpegModule();
- CCodec_Jbig2Module* GetJbig2Module();
- CCodec_FlateModule* GetFlateModule();
-
private:
CPDF_ModuleMgr();
~CPDF_ModuleMgr();
void InitPageModule();
- void InitCodecModule();
- void LoadCodecModules();
void LoadEmbeddedMaps();
void LoadEmbeddedGB1CMaps();
void LoadEmbeddedCNS1CMaps();
void LoadEmbeddedJapan1CMaps();
void LoadEmbeddedKorea1CMaps();
- std::unique_ptr<CCodec_ModuleMgr> m_pCodecModule;
std::unique_ptr<CPDF_PageModule> m_pPageModule;
std::unique_ptr<fpdfapi::UnsupportedInfoAdapter> m_pUnsupportInfoAdapter;
};
diff --git a/core/fpdfapi/page/cpdf_docpagedata.cpp b/core/fpdfapi/page/cpdf_docpagedata.cpp
index b311192..452f1a0 100644
--- a/core/fpdfapi/page/cpdf_docpagedata.cpp
+++ b/core/fpdfapi/page/cpdf_docpagedata.cpp
@@ -12,7 +12,6 @@
#include <utility>
#include "core/fdrm/fx_crypt.h"
-#include "core/fpdfapi/cpdf_modulemgr.h"
#include "core/fpdfapi/font/cpdf_type1font.h"
#include "core/fpdfapi/page/cpdf_iccprofile.h"
#include "core/fpdfapi/page/cpdf_image.h"
diff --git a/core/fpdfapi/page/cpdf_image.cpp b/core/fpdfapi/page/cpdf_image.cpp
index 1d01edb..322666f 100644
--- a/core/fpdfapi/page/cpdf_image.cpp
+++ b/core/fpdfapi/page/cpdf_image.cpp
@@ -12,7 +12,6 @@
#include <vector>
#include "constants/stream_dict_common.h"
-#include "core/fpdfapi/cpdf_modulemgr.h"
#include "core/fpdfapi/page/cpdf_page.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_boolean.h"
@@ -26,6 +25,7 @@
#include "core/fpdfapi/render/cpdf_dibbase.h"
#include "core/fpdfapi/render/cpdf_pagerendercache.h"
#include "core/fxcodec/codec/ccodec_jpegmodule.h"
+#include "core/fxcodec/fx_codec.h"
#include "core/fxcrt/fx_stream.h"
#include "core/fxge/dib/cfx_dibitmap.h"
#include "core/fxge/fx_dib.h"
@@ -88,7 +88,7 @@
int32_t num_comps;
int32_t bits;
bool color_trans;
- if (!CPDF_ModuleMgr::Get()->GetJpegModule()->LoadInfo(
+ if (!CCodec_ModuleMgr::GetInstance()->GetJpegModule()->LoadInfo(
src_span, &width, &height, &num_comps, &bits, &color_trans)) {
return nullptr;
}
diff --git a/core/fpdfapi/page/cpdf_streamparser.cpp b/core/fpdfapi/page/cpdf_streamparser.cpp
index f7f18c1..3b34131 100644
--- a/core/fpdfapi/page/cpdf_streamparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamparser.cpp
@@ -14,7 +14,6 @@
#include <utility>
#include "constants/stream_dict_common.h"
-#include "core/fpdfapi/cpdf_modulemgr.h"
#include "core/fpdfapi/page/cpdf_docpagedata.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_boolean.h"
@@ -93,7 +92,7 @@
}
if (decoder == "DCTDecode") {
std::unique_ptr<CCodec_ScanlineDecoder> pDecoder =
- CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder(
+ CCodec_ModuleMgr::GetInstance()->GetJpegModule()->CreateDecoder(
src_span, width, height, 0,
!pParam || pParam->GetIntegerFor("ColorTransform", 1));
return DecodeAllScanlines(std::move(pDecoder));
diff --git a/core/fpdfapi/render/cpdf_dibbase.cpp b/core/fpdfapi/render/cpdf_dibbase.cpp
index e82ce3c..4a39067 100644
--- a/core/fpdfapi/render/cpdf_dibbase.cpp
+++ b/core/fpdfapi/render/cpdf_dibbase.cpp
@@ -283,7 +283,8 @@
return LoadState::kFail;
FXCODEC_STATUS iDecodeStatus;
- CCodec_Jbig2Module* pJbig2Module = CPDF_ModuleMgr::Get()->GetJbig2Module();
+ CCodec_Jbig2Module* pJbig2Module =
+ CCodec_ModuleMgr::GetInstance()->GetJbig2Module();
if (!m_pJbig2Context) {
m_pJbig2Context = pdfium::MakeUnique<CCodec_Jbig2Context>();
if (m_pStreamAcc->GetImageParam()) {
@@ -512,7 +513,8 @@
bool CPDF_DIBBase::CreateDCTDecoder(pdfium::span<const uint8_t> src_span,
const CPDF_Dictionary* pParams) {
- CCodec_JpegModule* pJpegModule = CPDF_ModuleMgr::Get()->GetJpegModule();
+ CCodec_JpegModule* pJpegModule =
+ CCodec_ModuleMgr::GetInstance()->GetJpegModule();
m_pDecoder = pJpegModule->CreateDecoder(
src_span, m_Width, m_Height, m_nComponents,
!pParams || pParams->GetIntegerFor("ColorTransform", 1));
diff --git a/core/fxcodec/codec/ccodec_progressivedecoder_unittest.cpp b/core/fxcodec/codec/ccodec_progressivedecoder_unittest.cpp
index 8bc1143..9384c16 100644
--- a/core/fxcodec/codec/ccodec_progressivedecoder_unittest.cpp
+++ b/core/fxcodec/codec/ccodec_progressivedecoder_unittest.cpp
@@ -368,32 +368,36 @@
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- auto mgr = pdfium::MakeUnique<CCodec_ModuleMgr>();
- mgr->SetGifModule(pdfium::MakeUnique<CCodec_GifModule>());
+ CCodec_ModuleMgr::Create();
+ CCodec_ModuleMgr::GetInstance()->SetGifModule(
+ pdfium::MakeUnique<CCodec_GifModule>());
+ {
+ std::unique_ptr<CCodec_ProgressiveDecoder> decoder =
+ CCodec_ModuleMgr::GetInstance()->CreateProgressiveDecoder();
- std::unique_ptr<CCodec_ProgressiveDecoder> decoder =
- mgr->CreateProgressiveDecoder();
- auto source = pdfium::MakeRetain<CFX_ReadOnlyMemoryStream>(kInput);
- CFX_DIBAttribute attr;
- FXCODEC_STATUS status =
- decoder->LoadImageInfo(source, FXCODEC_IMAGE_GIF, &attr, true);
- ASSERT_EQ(FXCODEC_STATUS_FRAME_READY, status);
+ auto source = pdfium::MakeRetain<CFX_ReadOnlyMemoryStream>(kInput);
+ CFX_DIBAttribute attr;
+ FXCODEC_STATUS status =
+ decoder->LoadImageInfo(source, FXCODEC_IMAGE_GIF, &attr, true);
+ ASSERT_EQ(FXCODEC_STATUS_FRAME_READY, status);
- ASSERT_EQ(98, decoder->GetWidth());
- ASSERT_EQ(6945, decoder->GetHeight());
+ ASSERT_EQ(98, decoder->GetWidth());
+ ASSERT_EQ(6945, decoder->GetHeight());
- auto bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
- bitmap->Create(decoder->GetWidth(), decoder->GetHeight(), FXDIB_Argb);
+ auto bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
+ bitmap->Create(decoder->GetWidth(), decoder->GetHeight(), FXDIB_Argb);
- size_t frames;
- std::tie(status, frames) = decoder->GetFrames();
- ASSERT_EQ(FXCODEC_STATUS_DECODE_READY, status);
- ASSERT_EQ(1u, frames);
+ size_t frames;
+ std::tie(status, frames) = decoder->GetFrames();
+ ASSERT_EQ(FXCODEC_STATUS_DECODE_READY, status);
+ ASSERT_EQ(1u, frames);
- status = decoder->StartDecode(bitmap, 0, 0, bitmap->GetWidth(),
- bitmap->GetHeight());
- while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE)
- status = decoder->ContinueDecode();
- EXPECT_EQ(FXCODEC_STATUS_DECODE_FINISH, status);
+ status = decoder->StartDecode(bitmap, 0, 0, bitmap->GetWidth(),
+ bitmap->GetHeight());
+ while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE)
+ status = decoder->ContinueDecode();
+ EXPECT_EQ(FXCODEC_STATUS_DECODE_FINISH, status);
+ }
+ CCodec_ModuleMgr::Destroy();
}
#endif // PDF_ENABLE_XFA_GIF
diff --git a/core/fxcodec/codec/fx_codec.cpp b/core/fxcodec/codec/fx_codec.cpp
index 0ffaabc..abb8017 100644
--- a/core/fxcodec/codec/fx_codec.cpp
+++ b/core/fxcodec/codec/fx_codec.cpp
@@ -19,9 +19,50 @@
#include "third_party/base/logging.h"
#include "third_party/base/ptr_util.h"
+namespace {
+
+CCodec_ModuleMgr* g_CCodecModuleMgr = nullptr;
+
+} // namespace
+
+// static
+void CCodec_ModuleMgr::Create() {
+ ASSERT(!g_CCodecModuleMgr);
+ g_CCodecModuleMgr = new CCodec_ModuleMgr();
+}
+
+// static
+void CCodec_ModuleMgr::Destroy() {
+ ASSERT(g_CCodecModuleMgr);
+ delete g_CCodecModuleMgr;
+ g_CCodecModuleMgr = nullptr;
+}
+
+// static
+CCodec_ModuleMgr* CCodec_ModuleMgr::GetInstance() {
+ ASSERT(g_CCodecModuleMgr);
+ return g_CCodecModuleMgr;
+}
+
CCodec_ModuleMgr::CCodec_ModuleMgr()
: m_pJpegModule(pdfium::MakeUnique<CCodec_JpegModule>()),
- m_pJbig2Module(pdfium::MakeUnique<CCodec_Jbig2Module>()) {}
+ m_pJbig2Module(pdfium::MakeUnique<CCodec_Jbig2Module>()) {
+#ifdef PDF_ENABLE_XFA_BMP
+ SetBmpModule(pdfium::MakeUnique<CCodec_BmpModule>());
+#endif
+
+#ifdef PDF_ENABLE_XFA_GIF
+ SetGifModule(pdfium::MakeUnique<CCodec_GifModule>());
+#endif
+
+#ifdef PDF_ENABLE_XFA_PNG
+ SetPngModule(pdfium::MakeUnique<CCodec_PngModule>());
+#endif
+
+#ifdef PDF_ENABLE_XFA_TIFF
+ SetTiffModule(pdfium::MakeUnique<CCodec_TiffModule>());
+#endif
+}
CCodec_ModuleMgr::~CCodec_ModuleMgr() = default;
diff --git a/core/fxcodec/fx_codec.h b/core/fxcodec/fx_codec.h
index 034d6ce..8d3bfdd 100644
--- a/core/fxcodec/fx_codec.h
+++ b/core/fxcodec/fx_codec.h
@@ -54,8 +54,10 @@
class CCodec_ModuleMgr {
public:
- CCodec_ModuleMgr();
- ~CCodec_ModuleMgr();
+ // Per-process singleton managed by callers.
+ static void Create();
+ static void Destroy();
+ static CCodec_ModuleMgr* GetInstance();
CCodec_JpegModule* GetJpegModule() const { return m_pJpegModule.get(); }
CCodec_Jbig2Module* GetJbig2Module() const { return m_pJbig2Module.get(); }
@@ -92,7 +94,10 @@
#endif // PDF_ENABLE_XFA_TIFF
#endif // PDF_ENABLE_XFA
- protected:
+ private:
+ CCodec_ModuleMgr();
+ ~CCodec_ModuleMgr();
+
std::unique_ptr<CCodec_JpegModule> m_pJpegModule;
std::unique_ptr<CCodec_Jbig2Module> m_pJbig2Module;
diff --git a/testing/fuzzers/xfa_codec_fuzzer.h b/testing/fuzzers/xfa_codec_fuzzer.h
index 31ab512..2729963 100644
--- a/testing/fuzzers/xfa_codec_fuzzer.h
+++ b/testing/fuzzers/xfa_codec_fuzzer.h
@@ -37,7 +37,16 @@
class XFACodecFuzzer {
public:
static int Fuzz(const uint8_t* data, size_t size, FXCODEC_IMAGE_TYPE type) {
- auto mgr = pdfium::MakeUnique<CCodec_ModuleMgr>();
+ CCodec_ModuleMgr::Create();
+ int sts = FuzzInternal(CCodec_ModuleMgr::GetInstance(), data, size, type);
+ CCodec_ModuleMgr::Destroy();
+ return sts;
+ }
+
+ static int FuzzInternal(CCodec_ModuleMgr* mgr,
+ const uint8_t* data,
+ size_t size,
+ FXCODEC_IMAGE_TYPE type) {
#ifdef PDF_ENABLE_XFA_BMP
mgr->SetBmpModule(pdfium::MakeUnique<CCodec_BmpModule>());
#endif // PDF_ENABLE_XFA_BMP
diff --git a/xfa/fxfa/cxfa_ffwidget.cpp b/xfa/fxfa/cxfa_ffwidget.cpp
index 8855738..15bbb14 100644
--- a/xfa/fxfa/cxfa_ffwidget.cpp
+++ b/xfa/fxfa/cxfa_ffwidget.cpp
@@ -155,7 +155,7 @@
FXCODEC_IMAGE_TYPE type,
int32_t& iImageXDpi,
int32_t& iImageYDpi) {
- CCodec_ModuleMgr* pCodecMgr = CPDF_ModuleMgr::Get()->GetCodecModule();
+ auto* pCodecMgr = CCodec_ModuleMgr::GetInstance();
std::unique_ptr<CCodec_ProgressiveDecoder> pProgressiveDecoder =
pCodecMgr->CreateProgressiveDecoder();