diff options
author | weili <weili@chromium.org> | 2016-10-03 12:10:55 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-10-03 12:10:56 -0700 |
commit | d61f958385be285f3f3897ef3a3f010048608f1c (patch) | |
tree | 446db3b167ede38585cfea3ffe8a5cf414d74ad2 /core/fpdfapi/fpdf_font/cpdf_type3font.cpp | |
parent | e5393582a7f5dbb655a97d64531638b302ee684e (diff) | |
download | pdfium-d61f958385be285f3f3897ef3a3f010048608f1c.tar.xz |
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
Diffstat (limited to 'core/fpdfapi/fpdf_font/cpdf_type3font.cpp')
-rw-r--r-- | core/fpdfapi/fpdf_font/cpdf_type3font.cpp | 19 |
1 files changed, 11 insertions, 8 deletions
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(); } |