From d61f958385be285f3f3897ef3a3f010048608f1c Mon Sep 17 00:00:00 2001 From: weili Date: Mon, 3 Oct 2016 12:10:55 -0700 Subject: Detect resursive loading of type3 font char to avoid infinite loop The original way of detecting loops was passing a level parameter through various functions. This missed some cases which also lead to load type3 font char, for example, FindFont() may call CheckType3FontMetrics() which may eventually lead to LoadChar(). The new way is to store the char loading depth, and abort when the depth exceeds the max. BUG=chromium:651304 Review-Url: https://codereview.chromium.org/2384853002 --- core/fpdfapi/fpdf_font/cpdf_cidfont.cpp | 4 ++-- core/fpdfapi/fpdf_font/cpdf_cidfont.h | 4 ++-- core/fpdfapi/fpdf_font/cpdf_font.h | 4 ++-- core/fpdfapi/fpdf_font/cpdf_simplefont.cpp | 4 ++-- core/fpdfapi/fpdf_font/cpdf_simplefont.h | 4 ++-- core/fpdfapi/fpdf_font/cpdf_type3font.cpp | 19 +++++++++++-------- core/fpdfapi/fpdf_font/cpdf_type3font.h | 8 +++++--- core/fpdfapi/fpdf_page/cpdf_textobject.cpp | 9 ++++----- core/fpdfapi/fpdf_page/cpdf_textobject.h | 3 +-- core/fpdfapi/fpdf_page/fpdf_page_parser.cpp | 2 +- 10 files changed, 32 insertions(+), 29 deletions(-) (limited to 'core/fpdfapi') diff --git a/core/fpdfapi/fpdf_font/cpdf_cidfont.cpp b/core/fpdfapi/fpdf_font/cpdf_cidfont.cpp index ce7d5090d5..45db54fa67 100644 --- a/core/fpdfapi/fpdf_font/cpdf_cidfont.cpp +++ b/core/fpdfapi/fpdf_font/cpdf_cidfont.cpp @@ -428,7 +428,7 @@ bool CPDF_CIDFont::Load() { return true; } -FX_RECT CPDF_CIDFont::GetCharBBox(uint32_t charcode, int level) { +FX_RECT CPDF_CIDFont::GetCharBBox(uint32_t charcode) { if (charcode < 256 && m_CharBBox[charcode].right != -1) return m_CharBBox[charcode]; @@ -499,7 +499,7 @@ FX_RECT CPDF_CIDFont::GetCharBBox(uint32_t charcode, int level) { return rect; } -int CPDF_CIDFont::GetCharWidthF(uint32_t charcode, int level) { +int CPDF_CIDFont::GetCharWidthF(uint32_t charcode) { if (charcode < 0x80 && m_bAnsiWidthsFixed) return (charcode >= 32 && charcode < 127) ? 500 : 0; diff --git a/core/fpdfapi/fpdf_font/cpdf_cidfont.h b/core/fpdfapi/fpdf_font/cpdf_cidfont.h index 2c7df93b64..3e8c042c75 100644 --- a/core/fpdfapi/fpdf_font/cpdf_cidfont.h +++ b/core/fpdfapi/fpdf_font/cpdf_cidfont.h @@ -41,8 +41,8 @@ class CPDF_CIDFont : public CPDF_Font { const CPDF_CIDFont* AsCIDFont() const override; CPDF_CIDFont* AsCIDFont() override; int GlyphFromCharCode(uint32_t charcode, bool* pVertGlyph) override; - int GetCharWidthF(uint32_t charcode, int level = 0) override; - FX_RECT GetCharBBox(uint32_t charcode, int level = 0) override; + int GetCharWidthF(uint32_t charcode) override; + FX_RECT GetCharBBox(uint32_t charcode) override; uint32_t GetNextChar(const FX_CHAR* pString, int nStrLen, int& offset) const override; diff --git a/core/fpdfapi/fpdf_font/cpdf_font.h b/core/fpdfapi/fpdf_font/cpdf_font.h index 04f942c03c..0d2f50b61a 100644 --- a/core/fpdfapi/fpdf_font/cpdf_font.h +++ b/core/fpdfapi/fpdf_font/cpdf_font.h @@ -91,8 +91,8 @@ class CPDF_Font { uint32_t FallbackFontFromCharcode(uint32_t charcode); int FallbackGlyphFromCharcode(int fallbackFont, uint32_t charcode); - virtual int GetCharWidthF(uint32_t charcode, int level = 0) = 0; - virtual FX_RECT GetCharBBox(uint32_t charcode, int level = 0) = 0; + virtual int GetCharWidthF(uint32_t charcode) = 0; + virtual FX_RECT GetCharBBox(uint32_t charcode) = 0; CPDF_Document* m_pDocument; CFX_Font m_Font; diff --git a/core/fpdfapi/fpdf_font/cpdf_simplefont.cpp b/core/fpdfapi/fpdf_font/cpdf_simplefont.cpp index dda642380f..3bb3730fb5 100644 --- a/core/fpdfapi/fpdf_font/cpdf_simplefont.cpp +++ b/core/fpdfapi/fpdf_font/cpdf_simplefont.cpp @@ -78,7 +78,7 @@ void CPDF_SimpleFont::LoadCharMetrics(int charcode) { } } -int CPDF_SimpleFont::GetCharWidthF(uint32_t charcode, int level) { +int CPDF_SimpleFont::GetCharWidthF(uint32_t charcode) { if (charcode > 0xff) charcode = 0; @@ -91,7 +91,7 @@ int CPDF_SimpleFont::GetCharWidthF(uint32_t charcode, int level) { return m_CharWidth[charcode]; } -FX_RECT CPDF_SimpleFont::GetCharBBox(uint32_t charcode, int level) { +FX_RECT CPDF_SimpleFont::GetCharBBox(uint32_t charcode) { if (charcode > 0xff) charcode = 0; diff --git a/core/fpdfapi/fpdf_font/cpdf_simplefont.h b/core/fpdfapi/fpdf_font/cpdf_simplefont.h index 47067687a3..f286c1a228 100644 --- a/core/fpdfapi/fpdf_font/cpdf_simplefont.h +++ b/core/fpdfapi/fpdf_font/cpdf_simplefont.h @@ -20,8 +20,8 @@ class CPDF_SimpleFont : public CPDF_Font { ~CPDF_SimpleFont() override; // CPDF_Font - int GetCharWidthF(uint32_t charcode, int level = 0) override; - FX_RECT GetCharBBox(uint32_t charcode, int level = 0) override; + int GetCharWidthF(uint32_t charcode) override; + FX_RECT GetCharBBox(uint32_t charcode) override; int GlyphFromCharCode(uint32_t charcode, bool* pVertGlyph) override; bool IsUnicodeCompatible() const override; CFX_WideString UnicodeFromCharCode(uint32_t charcode) const override; diff --git a/core/fpdfapi/fpdf_font/cpdf_type3font.cpp b/core/fpdfapi/fpdf_font/cpdf_type3font.cpp index 4c81202bc4..e43ccda904 100644 --- a/core/fpdfapi/fpdf_font/cpdf_type3font.cpp +++ b/core/fpdfapi/fpdf_font/cpdf_type3font.cpp @@ -19,7 +19,8 @@ CPDF_Type3Font::CPDF_Type3Font() : m_pCharProcs(nullptr), m_pPageResources(nullptr), - m_pFontResources(nullptr) { + m_pFontResources(nullptr), + m_CharLoadingDepth(0) { FXSYS_memset(m_CharWidthL, 0, sizeof(m_CharWidthL)); } @@ -87,8 +88,8 @@ void CPDF_Type3Font::CheckType3FontMetrics() { CheckFontMetrics(); } -CPDF_Type3Char* CPDF_Type3Font::LoadChar(uint32_t charcode, int level) { - if (level >= _FPDF_MAX_TYPE3_FORM_LEVEL_) +CPDF_Type3Char* CPDF_Type3Font::LoadChar(uint32_t charcode) { + if (m_CharLoadingDepth >= _FPDF_MAX_TYPE3_FORM_LEVEL_) return nullptr; auto it = m_CacheMap.find(charcode); @@ -111,7 +112,9 @@ CPDF_Type3Char* CPDF_Type3Font::LoadChar(uint32_t charcode, int level) { // This can trigger recursion into this method. The content of |m_CacheMap| // can change as a result. Thus after it returns, check the cache again for // a cache hit. - pNewChar->m_pForm->ParseContent(nullptr, nullptr, pNewChar.get(), level + 1); + m_CharLoadingDepth++; + pNewChar->m_pForm->ParseContent(nullptr, nullptr, pNewChar.get()); + m_CharLoadingDepth--; it = m_CacheMap.find(charcode); if (it != m_CacheMap.end()) return it->second.get(); @@ -139,18 +142,18 @@ CPDF_Type3Char* CPDF_Type3Font::LoadChar(uint32_t charcode, int level) { return pCachedChar; } -int CPDF_Type3Font::GetCharWidthF(uint32_t charcode, int level) { +int CPDF_Type3Font::GetCharWidthF(uint32_t charcode) { if (charcode >= FX_ArraySize(m_CharWidthL)) charcode = 0; if (m_CharWidthL[charcode]) return m_CharWidthL[charcode]; - const CPDF_Type3Char* pChar = LoadChar(charcode, level); + const CPDF_Type3Char* pChar = LoadChar(charcode); return pChar ? pChar->m_Width : 0; } -FX_RECT CPDF_Type3Font::GetCharBBox(uint32_t charcode, int level) { - const CPDF_Type3Char* pChar = LoadChar(charcode, level); +FX_RECT CPDF_Type3Font::GetCharBBox(uint32_t charcode) { + const CPDF_Type3Char* pChar = LoadChar(charcode); return pChar ? pChar->m_BBox : FX_RECT(); } diff --git a/core/fpdfapi/fpdf_font/cpdf_type3font.h b/core/fpdfapi/fpdf_font/cpdf_type3font.h index 2b840f2267..03078298f1 100644 --- a/core/fpdfapi/fpdf_font/cpdf_type3font.h +++ b/core/fpdfapi/fpdf_font/cpdf_type3font.h @@ -26,13 +26,13 @@ class CPDF_Type3Font : public CPDF_SimpleFont { bool IsType3Font() const override; const CPDF_Type3Font* AsType3Font() const override; CPDF_Type3Font* AsType3Font() override; - int GetCharWidthF(uint32_t charcode, int level = 0) override; - FX_RECT GetCharBBox(uint32_t charcode, int level = 0) override; + int GetCharWidthF(uint32_t charcode) override; + FX_RECT GetCharBBox(uint32_t charcode) override; void SetPageResources(CPDF_Dictionary* pResources) { m_pPageResources = pResources; } - CPDF_Type3Char* LoadChar(uint32_t charcode, int level = 0); + CPDF_Type3Char* LoadChar(uint32_t charcode); void CheckType3FontMetrics(); CFX_Matrix& GetFontMatrix() { return m_FontMatrix; } @@ -52,6 +52,8 @@ class CPDF_Type3Font : public CPDF_SimpleFont { CPDF_Dictionary* m_pPageResources; CPDF_Dictionary* m_pFontResources; std::map> m_CacheMap; + // The depth char loading is in, to avoid recurive calling LoadChar(). + int m_CharLoadingDepth; }; #endif // CORE_FPDFAPI_FPDF_FONT_CPDF_TYPE3FONT_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_textobject.cpp b/core/fpdfapi/fpdf_page/cpdf_textobject.cpp index 4b9f335ea3..1119d2965f 100644 --- a/core/fpdfapi/fpdf_page/cpdf_textobject.cpp +++ b/core/fpdfapi/fpdf_page/cpdf_textobject.cpp @@ -217,7 +217,7 @@ FX_FLOAT CPDF_TextObject::GetCharWidth(uint32_t charcode) const { bVertWriting = pCIDFont->IsVertWriting(); } if (!bVertWriting) - return pFont->GetCharWidthF(charcode, 0) * fontsize; + return pFont->GetCharWidthF(charcode) * fontsize; uint16_t CID = pCIDFont->CIDFromCharCode(charcode); return pCIDFont->GetVertWidth(CID) * fontsize; @@ -241,8 +241,7 @@ FX_FLOAT CPDF_TextObject::GetFontSize() const { void CPDF_TextObject::CalcPositionData(FX_FLOAT* pTextAdvanceX, FX_FLOAT* pTextAdvanceY, - FX_FLOAT horz_scale, - int level) { + FX_FLOAT horz_scale) { FX_FLOAT curpos = 0; FX_FLOAT min_x = 10000 * 1.0f; FX_FLOAT max_x = -10000 * 1.0f; @@ -265,7 +264,7 @@ void CPDF_TextObject::CalcPositionData(FX_FLOAT* pTextAdvanceX, } m_pCharPos[i - 1] = curpos; } - FX_RECT char_rect = pFont->GetCharBBox(charcode, level); + FX_RECT char_rect = pFont->GetCharBBox(charcode); FX_FLOAT charwidth; if (!bVertWriting) { if (min_y > char_rect.top) { @@ -294,7 +293,7 @@ void CPDF_TextObject::CalcPositionData(FX_FLOAT* pTextAdvanceX, if (max_x < char_right) { max_x = char_right; } - charwidth = pFont->GetCharWidthF(charcode, level) * fontsize / 1000; + charwidth = pFont->GetCharWidthF(charcode) * fontsize / 1000; } else { uint16_t CID = pCIDFont->CIDFromCharCode(charcode); short vx; diff --git a/core/fpdfapi/fpdf_page/cpdf_textobject.h b/core/fpdfapi/fpdf_page/cpdf_textobject.h index c09da96040..05a08a9c89 100644 --- a/core/fpdfapi/fpdf_page/cpdf_textobject.h +++ b/core/fpdfapi/fpdf_page/cpdf_textobject.h @@ -56,8 +56,7 @@ class CPDF_TextObject : public CPDF_PageObject { void CalcPositionData(FX_FLOAT* pTextAdvanceX, FX_FLOAT* pTextAdvanceY, - FX_FLOAT horz_scale, - int level = 0); + FX_FLOAT horz_scale); FX_FLOAT m_PosX; FX_FLOAT m_PosY; diff --git a/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp b/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp index 18a2e2d882..4fc4bdc934 100644 --- a/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp +++ b/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp @@ -1252,7 +1252,7 @@ void CPDF_StreamContentParser::AddTextObject(CFX_ByteString* pStrs, FX_FLOAT x_advance; FX_FLOAT y_advance; pText->CalcPositionData(&x_advance, &y_advance, - m_pCurStates->m_TextHorzScale, m_Level); + m_pCurStates->m_TextHorzScale); m_pCurStates->m_TextX += x_advance; m_pCurStates->m_TextY += y_advance; if (TextRenderingModeIsClipMode(text_mode)) { -- cgit v1.2.3