| 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 bdbb939148ced7c1f902924745106a58bc7169b4..7e9ca8e3c579768c4350f6ddc5f02b3db5a0ef64 100644
|
| --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp
|
| +++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp
|
| @@ -112,13 +112,19 @@ CPDF_Parser::CPDF_Parser() {
|
| m_bOwnFileRead = TRUE;
|
| m_FileVersion = 0;
|
| m_bForceUseSecurityHandler = FALSE;
|
| + m_dwLastObjnum = 0;
|
| }
|
| CPDF_Parser::~CPDF_Parser() {
|
| CloseParser(FALSE);
|
| }
|
| -FX_DWORD CPDF_Parser::GetLastObjNum() {
|
| - FX_DWORD dwSize = m_CrossRef.GetSize();
|
| - return dwSize ? dwSize - 1 : 0;
|
| +void CPDF_Parser::SetLastObjNum(FX_DWORD num) {
|
| + m_dwLastObjnum = std::max(m_dwLastObjnum, num);
|
| +}
|
| +FX_DWORD CPDF_Parser::GetLastObjNum() const {
|
| + return m_ObjectInfo.empty() ? 0 : m_dwLastObjnum;
|
| +}
|
| +FX_DWORD CPDF_Parser::GetSize() const {
|
| + return m_ObjectInfo.empty() ? 0 : m_dwLastObjnum + 1;
|
| }
|
| void CPDF_Parser::SetEncryptDictionary(CPDF_Dictionary* pDict) {
|
| m_pEncryptDict = pDict;
|
| @@ -150,7 +156,8 @@ void CPDF_Parser::CloseParser(FX_BOOL bReParse) {
|
| m_ObjCache.clear();
|
|
|
| m_SortedOffset.RemoveAll();
|
| - m_CrossRef.RemoveAll();
|
| + m_ObjectInfo.clear();
|
| + m_dwLastObjnum = 0;
|
| m_V5Type.RemoveAll();
|
| m_ObjVersion.RemoveAll();
|
| int32_t iLen = m_Trailers.GetSize();
|
| @@ -331,14 +338,15 @@ void CPDF_Parser::ReleaseEncryptHandler() {
|
| }
|
| }
|
| FX_FILESIZE CPDF_Parser::GetObjectOffset(FX_DWORD objnum) {
|
| - if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {
|
| + if (objnum >= GetSize()) {
|
| return 0;
|
| }
|
| if (m_V5Type[objnum] == 1) {
|
| - return m_CrossRef[objnum];
|
| + return m_ObjectInfo[objnum].pos;
|
| }
|
| if (m_V5Type[objnum] == 2) {
|
| - return m_CrossRef[(int32_t)m_CrossRef[objnum]];
|
| + FX_FILESIZE pos = m_ObjectInfo[objnum].pos;
|
| + return m_ObjectInfo[pos].pos;
|
| }
|
| return 0;
|
| }
|
| @@ -355,7 +363,8 @@ FX_BOOL CPDF_Parser::LoadAllCrossRefV4(FX_FILESIZE xrefpos) {
|
| if (xrefsize <= 0 || xrefsize > (1 << 20)) {
|
| return FALSE;
|
| }
|
| - m_CrossRef.SetSize(xrefsize);
|
| + m_ObjectInfo[0].pos = 0;
|
| + SetLastObjNum(static_cast<FX_DWORD>(xrefsize));
|
| m_V5Type.SetSize(xrefsize);
|
| CFX_FileSizeArray CrossRefList, XRefStreamList;
|
| CrossRefList.Add(xrefpos);
|
| @@ -458,7 +467,8 @@ FX_BOOL CPDF_Parser::LoadLinearizedCrossRefV4(FX_FILESIZE pos,
|
| FX_DWORD objnum = start_objnum + block * 1024 + i;
|
| char* pEntry = pBuf + i * recordsize;
|
| if (pEntry[17] == 'f') {
|
| - m_CrossRef.SetAtGrow(objnum, 0);
|
| + m_ObjectInfo[objnum].pos = 0;
|
| + SetLastObjNum(objnum);
|
| m_V5Type.SetAtGrow(objnum, 0);
|
| } else {
|
| int32_t offset = FXSYS_atoi(pEntry);
|
| @@ -468,18 +478,19 @@ FX_BOOL CPDF_Parser::LoadLinearizedCrossRefV4(FX_FILESIZE pos,
|
| return FALSE;
|
| }
|
| }
|
| - m_CrossRef.SetAtGrow(objnum, offset);
|
| + m_ObjectInfo[objnum].pos = offset;
|
| + SetLastObjNum(objnum);
|
| int32_t version = FXSYS_atoi(pEntry + 11);
|
| if (version >= 1) {
|
| m_bVersionUpdated = TRUE;
|
| }
|
| m_ObjVersion.SetAtGrow(objnum, version);
|
| - if (m_CrossRef[objnum] < m_Syntax.m_FileLen) {
|
| + if (m_ObjectInfo[objnum].pos < m_Syntax.m_FileLen) {
|
| void* pResult = FXSYS_bsearch(
|
| - &m_CrossRef[objnum], m_SortedOffset.GetData(),
|
| + &m_ObjectInfo[objnum].pos, m_SortedOffset.GetData(),
|
| m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), CompareFileSize);
|
| if (!pResult) {
|
| - m_SortedOffset.Add(m_CrossRef[objnum]);
|
| + m_SortedOffset.Add(m_ObjectInfo[objnum].pos);
|
| }
|
| }
|
| m_V5Type.SetAtGrow(objnum, 1);
|
| @@ -541,7 +552,8 @@ bool CPDF_Parser::LoadCrossRefV4(FX_FILESIZE pos,
|
| FX_DWORD objnum = start_objnum + block * 1024 + i;
|
| char* pEntry = pBuf + i * recordsize;
|
| if (pEntry[17] == 'f') {
|
| - m_CrossRef.SetAtGrow(objnum, 0);
|
| + m_ObjectInfo[objnum].pos = 0;
|
| + SetLastObjNum(objnum);
|
| m_V5Type.SetAtGrow(objnum, 0);
|
| } else {
|
| FX_FILESIZE offset = (FX_FILESIZE)FXSYS_atoi64(pEntry);
|
| @@ -551,15 +563,16 @@ bool CPDF_Parser::LoadCrossRefV4(FX_FILESIZE pos,
|
| return false;
|
| }
|
| }
|
| - m_CrossRef.SetAtGrow(objnum, offset);
|
| + m_ObjectInfo[objnum].pos = offset;
|
| + SetLastObjNum(objnum);
|
| int32_t version = FXSYS_atoi(pEntry + 11);
|
| if (version >= 1) {
|
| m_bVersionUpdated = TRUE;
|
| }
|
| m_ObjVersion.SetAtGrow(objnum, version);
|
| - if (m_CrossRef[objnum] < m_Syntax.m_FileLen &&
|
| - !FindPosInOffsets(m_CrossRef[objnum])) {
|
| - m_SortedOffset.Add(m_CrossRef[objnum]);
|
| + if (m_ObjectInfo[objnum].pos < m_Syntax.m_FileLen &&
|
| + !FindPosInOffsets(m_ObjectInfo[objnum].pos)) {
|
| + m_SortedOffset.Add(m_ObjectInfo[objnum].pos);
|
| }
|
| m_V5Type.SetAtGrow(objnum, 1);
|
| }
|
| @@ -592,7 +605,8 @@ FX_BOOL CPDF_Parser::LoadAllCrossRefV5(FX_FILESIZE xrefpos) {
|
| }
|
|
|
| FX_BOOL CPDF_Parser::RebuildCrossRef() {
|
| - m_CrossRef.RemoveAll();
|
| + m_ObjectInfo.clear();
|
| + m_dwLastObjnum = 0;
|
| m_V5Type.RemoveAll();
|
| m_SortedOffset.RemoveAll();
|
| m_ObjVersion.RemoveAll();
|
| @@ -794,18 +808,18 @@ FX_BOOL CPDF_Parser::RebuildCrossRef() {
|
| } else {
|
| i += (FX_DWORD)nLen;
|
| }
|
| - if (m_CrossRef.GetSize() > (int32_t)objnum &&
|
| - m_CrossRef[objnum]) {
|
| + if (GetSize() > objnum && m_ObjectInfo[objnum].pos) {
|
| if (pObject) {
|
| FX_DWORD oldgen = m_ObjVersion.GetAt(objnum);
|
| - m_CrossRef[objnum] = obj_pos;
|
| + m_ObjectInfo[objnum].pos = obj_pos;
|
| m_ObjVersion.SetAt(objnum, (int16_t)gennum);
|
| if (oldgen != gennum) {
|
| m_bVersionUpdated = TRUE;
|
| }
|
| }
|
| } else {
|
| - m_CrossRef.SetAtGrow(objnum, obj_pos);
|
| + m_ObjectInfo[objnum].pos = obj_pos;
|
| + SetLastObjNum(objnum);
|
| m_V5Type.SetAtGrow(objnum, 1);
|
| m_ObjVersion.SetAtGrow(objnum, (int16_t)gennum);
|
| }
|
| @@ -835,10 +849,8 @@ FX_BOOL CPDF_Parser::RebuildCrossRef() {
|
| CPDF_Object* pRoot = pTrailer->GetElement("Root");
|
| CPDF_Reference* pRef = ToReference(pRoot);
|
| if (!pRoot ||
|
| - (pRef &&
|
| - (FX_DWORD)m_CrossRef.GetSize() >
|
| - pRef->GetRefObjNum() &&
|
| - m_CrossRef.GetAt(pRef->GetRefObjNum()) != 0)) {
|
| + (pRef && GetSize() > pRef->GetRefObjNum() &&
|
| + m_ObjectInfo[pRef->GetRefObjNum()].pos != 0)) {
|
| FX_POSITION pos = pTrailer->GetStartPos();
|
| while (pos) {
|
| CFX_ByteString key;
|
| @@ -964,7 +976,7 @@ FX_BOOL CPDF_Parser::RebuildCrossRef() {
|
| m_SortedOffset.Add(offset);
|
| }
|
| FX_Free(buffer);
|
| - return m_pTrailer && m_CrossRef.GetSize() > 0;
|
| + return m_pTrailer && GetSize() > 0;
|
| }
|
|
|
| FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE* pos, FX_BOOL bMainXRef) {
|
| @@ -996,7 +1008,8 @@ FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE* pos, FX_BOOL bMainXRef) {
|
| }
|
| if (bMainXRef) {
|
| m_pTrailer = ToDictionary(pStream->GetDict()->Clone());
|
| - m_CrossRef.SetSize(size);
|
| + m_ObjectInfo[0].pos = 0;
|
| + SetLastObjNum(static_cast<FX_DWORD>(size));
|
| if (m_V5Type.SetSize(size)) {
|
| FXSYS_memset(m_V5Type.GetData(), 0, size);
|
| }
|
| @@ -1076,7 +1089,7 @@ FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE* pos, FX_BOOL bMainXRef) {
|
| if (m_V5Type[startnum + j] == 255) {
|
| FX_FILESIZE offset =
|
| GetVarInt(entrystart + WidthArray[0], WidthArray[1]);
|
| - m_CrossRef[startnum + j] = offset;
|
| + m_ObjectInfo[startnum + j].pos = offset;
|
| void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(),
|
| m_SortedOffset.GetSize(),
|
| sizeof(FX_FILESIZE), CompareFileSize);
|
| @@ -1090,11 +1103,11 @@ FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE* pos, FX_BOOL bMainXRef) {
|
| }
|
| m_V5Type[startnum + j] = type;
|
| if (type == 0) {
|
| - m_CrossRef[startnum + j] = 0;
|
| + m_ObjectInfo[startnum + j].pos = 0;
|
| } else {
|
| FX_FILESIZE offset =
|
| GetVarInt(entrystart + WidthArray[0], WidthArray[1]);
|
| - m_CrossRef[startnum + j] = offset;
|
| + m_ObjectInfo[startnum + j].pos = offset;
|
| if (type == 1) {
|
| void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(),
|
| m_SortedOffset.GetSize(),
|
| @@ -1139,7 +1152,7 @@ FX_DWORD CPDF_Parser::GetInfoObjNum() {
|
| }
|
| FX_BOOL CPDF_Parser::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm) {
|
| bForm = FALSE;
|
| - if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {
|
| + if (objnum >= GetSize()) {
|
| return TRUE;
|
| }
|
| if (m_V5Type[objnum] == 0) {
|
| @@ -1148,7 +1161,7 @@ FX_BOOL CPDF_Parser::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm) {
|
| if (m_V5Type[objnum] == 2) {
|
| return TRUE;
|
| }
|
| - FX_FILESIZE pos = m_CrossRef[objnum];
|
| + FX_FILESIZE pos = m_ObjectInfo[objnum].pos;
|
| void* pResult =
|
| FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(),
|
| sizeof(FX_FILESIZE), CompareFileSize);
|
| @@ -1172,11 +1185,11 @@ FX_BOOL CPDF_Parser::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm) {
|
| CPDF_Object* CPDF_Parser::ParseIndirectObject(CPDF_IndirectObjects* pObjList,
|
| FX_DWORD objnum,
|
| PARSE_CONTEXT* pContext) {
|
| - if (objnum >= (FX_DWORD)m_CrossRef.GetSize())
|
| + if (objnum >= GetSize())
|
| return nullptr;
|
|
|
| if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) {
|
| - FX_FILESIZE pos = m_CrossRef[objnum];
|
| + FX_FILESIZE pos = m_ObjectInfo[objnum].pos;
|
| if (pos <= 0)
|
| return nullptr;
|
| return ParseIndirectObjectAt(pObjList, pos, objnum, pContext);
|
| @@ -1184,7 +1197,7 @@ CPDF_Object* CPDF_Parser::ParseIndirectObject(CPDF_IndirectObjects* pObjList,
|
| if (m_V5Type[objnum] != 2)
|
| return nullptr;
|
|
|
| - CPDF_StreamAcc* pObjStream = GetObjectStream((FX_DWORD)m_CrossRef[objnum]);
|
| + CPDF_StreamAcc* pObjStream = GetObjectStream(m_ObjectInfo[objnum].pos);
|
| if (!pObjStream)
|
| return nullptr;
|
|
|
| @@ -1227,14 +1240,14 @@ CPDF_StreamAcc* CPDF_Parser::GetObjectStream(FX_DWORD objnum) {
|
| return pStreamAcc;
|
| }
|
| FX_FILESIZE CPDF_Parser::GetObjectSize(FX_DWORD objnum) {
|
| - if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {
|
| + if (objnum >= GetSize()) {
|
| return 0;
|
| }
|
| if (m_V5Type[objnum] == 2) {
|
| - objnum = (FX_DWORD)m_CrossRef[objnum];
|
| + objnum = m_ObjectInfo[objnum].pos;
|
| }
|
| if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) {
|
| - FX_FILESIZE offset = m_CrossRef[objnum];
|
| + FX_FILESIZE offset = m_ObjectInfo[objnum].pos;
|
| if (offset == 0) {
|
| return 0;
|
| }
|
| @@ -1257,11 +1270,11 @@ void CPDF_Parser::GetIndirectBinary(FX_DWORD objnum,
|
| FX_DWORD& size) {
|
| pBuffer = NULL;
|
| size = 0;
|
| - if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {
|
| + if (objnum >= GetSize()) {
|
| return;
|
| }
|
| if (m_V5Type[objnum] == 2) {
|
| - CPDF_StreamAcc* pObjStream = GetObjectStream((FX_DWORD)m_CrossRef[objnum]);
|
| + CPDF_StreamAcc* pObjStream = GetObjectStream(m_ObjectInfo[objnum].pos);
|
| if (!pObjStream)
|
| return;
|
|
|
| @@ -1295,7 +1308,7 @@ void CPDF_Parser::GetIndirectBinary(FX_DWORD objnum,
|
| if (m_V5Type[objnum] != 1)
|
| return;
|
|
|
| - FX_FILESIZE pos = m_CrossRef[objnum];
|
| + FX_FILESIZE pos = m_ObjectInfo[objnum].pos;
|
| if (pos == 0) {
|
| return;
|
| }
|
| @@ -1569,7 +1582,8 @@ FX_DWORD CPDF_Parser::StartAsynParse(IFX_FileRead* pFileAccess,
|
| }
|
| int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size");
|
| if (xrefsize > 0) {
|
| - m_CrossRef.SetSize(xrefsize);
|
| + m_ObjectInfo[0].pos = 0;
|
| + SetLastObjNum(static_cast<FX_DWORD>(xrefsize));
|
| m_V5Type.SetSize(xrefsize);
|
| }
|
| }
|
| @@ -2967,14 +2981,14 @@ FX_DWORD CPDF_DataAvail::GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset) {
|
| if (!pParser) {
|
| return 0;
|
| }
|
| - if (objnum >= (FX_DWORD)pParser->m_CrossRef.GetSize()) {
|
| + if (objnum >= pParser->GetSize()) {
|
| return 0;
|
| }
|
| if (pParser->m_V5Type[objnum] == 2) {
|
| - objnum = (FX_DWORD)pParser->m_CrossRef[objnum];
|
| + objnum = pParser->m_ObjectInfo[objnum].pos;
|
| }
|
| if (pParser->m_V5Type[objnum] == 1 || pParser->m_V5Type[objnum] == 255) {
|
| - offset = pParser->m_CrossRef[objnum];
|
| + offset = pParser->m_ObjectInfo[objnum].pos;
|
| if (offset == 0) {
|
| return 0;
|
| }
|
|
|