Chromium Code Reviews| Index: core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp |
| diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp |
| index 6251748d3ea1794f0bcff63694e4720cadf2b2d3..5e826d33a3bf4c153e75ee9dd80268965911b123 100644 |
| --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp |
| +++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp |
| @@ -141,6 +141,8 @@ void CPDF_Parser::CloseParser(FX_BOOL bReParse) { |
| delete pStream; |
| } |
| m_ObjectStreamMap.RemoveAll(); |
| + m_ObjCache.clear(); |
| + |
| m_SortedOffset.RemoveAll(); |
| m_CrossRef.RemoveAll(); |
| m_V5Type.RemoveAll(); |
| @@ -1201,15 +1203,24 @@ CPDF_Object* CPDF_Parser::ParseIndirectObject(CPDF_IndirectObjects* pObjList, |
| CPDF_SyntaxParser syntax; |
| syntax.InitParser(file.get(), 0); |
| int32_t offset = GetStreamFirst(pObjStream); |
| - for (int32_t i = GetStreamNCount(pObjStream); i > 0; --i) { |
| - FX_DWORD thisnum = syntax.GetDirectNum(); |
| - FX_DWORD thisoff = syntax.GetDirectNum(); |
| - if (thisnum == objnum) { |
| - syntax.RestorePos(offset + thisoff); |
| - return syntax.GetObject(pObjList, 0, 0, pContext); |
| + |
| + // Read object numbers from |pObjStream| into a cache. |
| + if (m_ObjCache.find(pObjStream) == m_ObjCache.end()) { |
| + FX_FILESIZE saved_pos = syntax.SavePos(); |
| + for (int32_t i = GetStreamNCount(pObjStream); i > 0; --i) { |
| + FX_DWORD thisnum = syntax.GetDirectNum(); |
| + FX_DWORD thisoff = syntax.GetDirectNum(); |
| + m_ObjCache[pObjStream][thisnum] = thisoff; |
| } |
| + syntax.RestorePos(saved_pos); |
|
jun_fang
2015/11/19 16:19:45
nit: It seems that there is no need to restore the
Lei Zhang
2015/11/20 07:11:42
Done. I needed it in an earlier iteration, but the
|
| } |
| - return nullptr; |
| + |
| + const auto it = m_ObjCache[pObjStream].find(objnum); |
| + if (it == m_ObjCache[pObjStream].end()) |
| + return nullptr; |
| + |
| + syntax.RestorePos(offset + it->second); |
| + return syntax.GetObject(pObjList, 0, 0, pContext); |
| } |
| CPDF_StreamAcc* CPDF_Parser::GetObjectStream(FX_DWORD objnum) { |
| @@ -1659,6 +1670,8 @@ FX_DWORD CPDF_Parser::LoadLinearizedMainXRefTable() { |
| delete pStream; |
| } |
| m_ObjectStreamMap.RemoveAll(); |
| + m_ObjCache.clear(); |
| + |
| if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) && |
| !LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) { |
| m_LastXRefOffset = 0; |