summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorthestig <thestig@chromium.org>2016-11-11 12:06:47 -0800
committerCommit bot <commit-bot@chromium.org>2016-11-11 12:06:47 -0800
commitdc40c40f40ed2415605da32f688091a57f53c9e6 (patch)
tree9fbd02dffbf9028c782fa28c707f2a819a8582c4
parent5937d0d03793caf73c8bb795ac06684596790e82 (diff)
downloadpdfium-dc40c40f40ed2415605da32f688091a57f53c9e6.tar.xz
Relax colorspace checks in CPDF_DIBSource::CreateDecoder().chromium/2917
Previously the log just made sure the colorspace and the image have exact matches for the number of colorspace components. Now, for some colorspace types, check the type and make sure the number of components meets or exceeds what is required by the spec. Also do some refactoring. BUG=chromium:650230 Review-Url: https://codereview.chromium.org/2486123002
-rw-r--r--core/fpdfapi/page/fpdf_page_colors.cpp12
-rw-r--r--core/fpdfapi/render/fpdf_render_loadimage.cpp96
-rw-r--r--core/fxcodec/fx_codec.h1
3 files changed, 73 insertions, 36 deletions
diff --git a/core/fpdfapi/page/fpdf_page_colors.cpp b/core/fpdfapi/page/fpdf_page_colors.cpp
index 455233abb5..69129e4f2b 100644
--- a/core/fpdfapi/page/fpdf_page_colors.cpp
+++ b/core/fpdfapi/page/fpdf_page_colors.cpp
@@ -21,6 +21,12 @@
namespace {
+FX_FLOAT NormalizeChannel(FX_FLOAT fVal) {
+ return std::min(std::max(fVal, 0.0f), 1.0f);
+}
+
+} // namespace
+
uint32_t ComponentsForFamily(int family) {
if (family == PDFCS_DEVICERGB)
return 3;
@@ -30,12 +36,6 @@ uint32_t ComponentsForFamily(int family) {
return 4;
}
-FX_FLOAT NormalizeChannel(FX_FLOAT fVal) {
- return std::min(std::max(fVal, 0.0f), 1.0f);
-}
-
-} // namespace
-
void sRGB_to_AdobeCMYK(FX_FLOAT R,
FX_FLOAT G,
FX_FLOAT B,
diff --git a/core/fpdfapi/render/fpdf_render_loadimage.cpp b/core/fpdfapi/render/fpdf_render_loadimage.cpp
index c3fe99018c..118f7849a9 100644
--- a/core/fpdfapi/render/fpdf_render_loadimage.cpp
+++ b/core/fpdfapi/render/fpdf_render_loadimage.cpp
@@ -58,6 +58,10 @@ bool IsAllowedBPCValue(int bpc) {
return bpc == 1 || bpc == 2 || bpc == 4 || bpc == 8 || bpc == 16;
}
+bool IsAllowedICCComponents(int nComp) {
+ return nComp == 1 || nComp == 3 || nComp == 4;
+}
+
template <typename T>
T ClampValue(T value, T max_value) {
value = std::min(value, max_value);
@@ -536,18 +540,43 @@ CCodec_ScanlineDecoder* FPDFAPI_CreateFlateDecoder(
int CPDF_DIBSource::CreateDecoder() {
const CFX_ByteString& decoder = m_pStreamAcc->GetImageDecoder();
- if (decoder.IsEmpty()) {
+ if (decoder.IsEmpty())
return 1;
- }
- if (m_bDoBpcCheck && m_bpc == 0) {
+
+ if (m_bDoBpcCheck && m_bpc == 0)
return 0;
+
+ if (decoder == "JPXDecode") {
+ LoadJpxBitmap();
+ return m_pCachedBitmap ? 1 : 0;
+ }
+ if (decoder == "JBIG2Decode") {
+ m_pCachedBitmap = pdfium::MakeUnique<CFX_DIBitmap>();
+ if (!m_pCachedBitmap->Create(
+ m_Width, m_Height, m_bImageMask ? FXDIB_1bppMask : FXDIB_1bppRgb)) {
+ m_pCachedBitmap.reset();
+ return 0;
+ }
+ m_Status = 1;
+ return 2;
}
+
const uint8_t* src_data = m_pStreamAcc->GetData();
uint32_t src_size = m_pStreamAcc->GetSize();
const CPDF_Dictionary* pParams = m_pStreamAcc->GetImageParam();
if (decoder == "CCITTFaxDecode") {
m_pDecoder.reset(FPDFAPI_CreateFaxDecoder(src_data, src_size, m_Width,
m_Height, pParams));
+ } else if (decoder == "FlateDecode") {
+ m_pDecoder.reset(FPDFAPI_CreateFlateDecoder(
+ src_data, src_size, m_Width, m_Height, m_nComponents, m_bpc, pParams));
+ } else if (decoder == "RunLengthDecode") {
+ m_pDecoder.reset(CPDF_ModuleMgr::Get()
+ ->GetCodecModule()
+ ->GetBasicModule()
+ ->CreateRunLengthDecoder(src_data, src_size, m_Width,
+ m_Height, m_nComponents,
+ m_bpc));
} else if (decoder == "DCTDecode") {
m_pDecoder.reset(CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder(
src_data, src_size, m_Width, m_Height, m_nComponents,
@@ -563,12 +592,41 @@ int CPDF_DIBSource::CreateDecoder() {
FX_Free(m_pCompData);
m_pCompData = nullptr;
m_nComponents = static_cast<uint32_t>(comps);
- if (m_pColorSpace &&
- m_pColorSpace->CountComponents() != m_nComponents) {
- return 0;
+ if (m_pColorSpace) {
+ switch (m_Family) {
+ case PDFCS_DEVICEGRAY:
+ case PDFCS_DEVICERGB:
+ case PDFCS_DEVICECMYK: {
+ uint32_t dwMinComps = ComponentsForFamily(m_Family);
+ if (m_pColorSpace->CountComponents() < dwMinComps ||
+ m_nComponents < dwMinComps) {
+ return 0;
+ }
+ break;
+ }
+ case PDFCS_LAB: {
+ if (m_nComponents != 3 || m_pColorSpace->CountComponents() < 3)
+ return 0;
+ break;
+ }
+ case PDFCS_ICCBASED: {
+ if (!IsAllowedICCComponents(m_nComponents) ||
+ !IsAllowedICCComponents(m_pColorSpace->CountComponents()) ||
+ m_pColorSpace->CountComponents() < m_nComponents) {
+ return 0;
+ }
+ break;
+ }
+ default: {
+ if (m_pColorSpace->CountComponents() != m_nComponents)
+ return 0;
+ break;
+ }
+ }
+ } else {
+ if (m_Family == PDFCS_LAB && m_nComponents != 3)
+ return 0;
}
- if (m_Family == PDFCS_LAB && m_nComponents != 3)
- return 0;
m_pCompData = GetDecodeAndMaskArray(m_bDefaultDecode, m_bColorKey);
if (!m_pCompData)
return 0;
@@ -578,28 +636,6 @@ int CPDF_DIBSource::CreateDecoder() {
src_data, src_size, m_Width, m_Height, m_nComponents, bTransform));
}
}
- } else if (decoder == "FlateDecode") {
- m_pDecoder.reset(FPDFAPI_CreateFlateDecoder(
- src_data, src_size, m_Width, m_Height, m_nComponents, m_bpc, pParams));
- } else if (decoder == "JPXDecode") {
- LoadJpxBitmap();
- return m_pCachedBitmap ? 1 : 0;
- } else if (decoder == "JBIG2Decode") {
- m_pCachedBitmap.reset(new CFX_DIBitmap);
- if (!m_pCachedBitmap->Create(
- m_Width, m_Height, m_bImageMask ? FXDIB_1bppMask : FXDIB_1bppRgb)) {
- m_pCachedBitmap.reset();
- return 0;
- }
- m_Status = 1;
- return 2;
- } else if (decoder == "RunLengthDecode") {
- m_pDecoder.reset(CPDF_ModuleMgr::Get()
- ->GetCodecModule()
- ->GetBasicModule()
- ->CreateRunLengthDecoder(src_data, src_size, m_Width,
- m_Height, m_nComponents,
- m_bpc));
}
if (!m_pDecoder)
return 0;
diff --git a/core/fxcodec/fx_codec.h b/core/fxcodec/fx_codec.h
index faf74d0902..bb4766567b 100644
--- a/core/fxcodec/fx_codec.h
+++ b/core/fxcodec/fx_codec.h
@@ -96,6 +96,7 @@ class CCodec_ModuleMgr {
};
void ReverseRGB(uint8_t* pDestBuf, const uint8_t* pSrcBuf, int pixels);
+uint32_t ComponentsForFamily(int family);
void sRGB_to_AdobeCMYK(FX_FLOAT R,
FX_FLOAT G,
FX_FLOAT B,