| OLD | NEW |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "../../../include/fpdfapi/fpdf_module.h" | 10 #include "../../../include/fpdfapi/fpdf_module.h" |
| 11 #include "../../../include/fpdfapi/fpdf_page.h" | 11 #include "../../../include/fpdfapi/fpdf_page.h" |
| 12 #include "../../../include/fpdfapi/fpdf_parser.h" | 12 #include "../../../include/fpdfapi/fpdf_parser.h" |
| 13 #include "../../../include/fxcrt/fx_safe_types.h" | 13 #include "../../../include/fxcrt/fx_safe_types.h" |
| 14 #include "../fpdf_page/pageint.h" | 14 #include "../fpdf_page/pageint.h" |
| 15 | 15 |
| 16 FX_BOOL IsSignatureDict(const CPDF_Dictionary* pDict) | 16 FX_BOOL IsSignatureDict(const CPDF_Dictionary* pDict) { |
| 17 { | 17 CPDF_Object* pType = pDict->GetElementValue(FX_BSTRC("Type")); |
| 18 CPDF_Object* pType = pDict->GetElementValue(FX_BSTRC("Type")); | 18 if (!pType) { |
| 19 pType = pDict->GetElementValue(FX_BSTRC("FT")); |
| 19 if (!pType) { | 20 if (!pType) { |
| 20 pType = pDict->GetElementValue(FX_BSTRC("FT")); | 21 return FALSE; |
| 21 if (!pType) { | 22 } |
| 22 return FALSE; | 23 } |
| 23 } | 24 if (pType->GetString() == FX_BSTRC("Sig")) { |
| 24 } | 25 return TRUE; |
| 25 if (pType->GetString() == FX_BSTRC("Sig")) { | 26 } |
| 26 return TRUE; | 27 return FALSE; |
| 27 } | 28 } |
| 28 return FALSE; | 29 static int _CompareFileSize(const void* p1, const void* p2) { |
| 29 } | 30 FX_FILESIZE ret = (*(FX_FILESIZE*)p1) - (*(FX_FILESIZE*)p2); |
| 30 static int _CompareFileSize(const void* p1, const void* p2) | 31 if (ret > 0) { |
| 31 { | 32 return 1; |
| 32 FX_FILESIZE ret = (*(FX_FILESIZE*)p1) - (*(FX_FILESIZE*)p2); | 33 } |
| 33 if (ret > 0) { | 34 if (ret < 0) { |
| 34 return 1; | 35 return -1; |
| 35 } | 36 } |
| 36 if (ret < 0) { | 37 return 0; |
| 37 return -1; | 38 } |
| 38 } | 39 |
| 39 return 0; | 40 CPDF_Parser::CPDF_Parser() { |
| 40 } | 41 m_pDocument = NULL; |
| 41 | 42 m_pTrailer = NULL; |
| 42 CPDF_Parser::CPDF_Parser() | 43 m_pEncryptDict = NULL; |
| 43 { | 44 m_pSecurityHandler = NULL; |
| 45 m_pLinearized = NULL; |
| 46 m_dwFirstPageNo = 0; |
| 47 m_dwXrefStartObjNum = 0; |
| 48 m_bOwnFileRead = TRUE; |
| 49 m_FileVersion = 0; |
| 50 m_bForceUseSecurityHandler = FALSE; |
| 51 } |
| 52 CPDF_Parser::~CPDF_Parser() { |
| 53 CloseParser(FALSE); |
| 54 } |
| 55 FX_DWORD CPDF_Parser::GetLastObjNum() { |
| 56 FX_DWORD dwSize = m_CrossRef.GetSize(); |
| 57 return dwSize ? dwSize - 1 : 0; |
| 58 } |
| 59 void CPDF_Parser::SetEncryptDictionary(CPDF_Dictionary* pDict) { |
| 60 m_pEncryptDict = pDict; |
| 61 } |
| 62 void CPDF_Parser::CloseParser(FX_BOOL bReParse) { |
| 63 m_bVersionUpdated = FALSE; |
| 64 if (!bReParse) { |
| 65 delete m_pDocument; |
| 44 m_pDocument = NULL; | 66 m_pDocument = NULL; |
| 67 } |
| 68 if (m_pTrailer) { |
| 69 m_pTrailer->Release(); |
| 45 m_pTrailer = NULL; | 70 m_pTrailer = NULL; |
| 46 m_pEncryptDict = NULL; | 71 } |
| 47 m_pSecurityHandler = NULL; | 72 ReleaseEncryptHandler(); |
| 73 SetEncryptDictionary(NULL); |
| 74 if (m_bOwnFileRead && m_Syntax.m_pFileAccess) { |
| 75 m_Syntax.m_pFileAccess->Release(); |
| 76 m_Syntax.m_pFileAccess = NULL; |
| 77 } |
| 78 FX_POSITION pos = m_ObjectStreamMap.GetStartPosition(); |
| 79 while (pos) { |
| 80 void* objnum; |
| 81 CPDF_StreamAcc* pStream; |
| 82 m_ObjectStreamMap.GetNextAssoc(pos, objnum, (void*&)pStream); |
| 83 delete pStream; |
| 84 } |
| 85 m_ObjectStreamMap.RemoveAll(); |
| 86 m_SortedOffset.RemoveAll(); |
| 87 m_CrossRef.RemoveAll(); |
| 88 m_V5Type.RemoveAll(); |
| 89 m_ObjVersion.RemoveAll(); |
| 90 int32_t iLen = m_Trailers.GetSize(); |
| 91 for (int32_t i = 0; i < iLen; ++i) { |
| 92 if (CPDF_Dictionary* trailer = m_Trailers.GetAt(i)) |
| 93 trailer->Release(); |
| 94 } |
| 95 m_Trailers.RemoveAll(); |
| 96 if (m_pLinearized) { |
| 97 m_pLinearized->Release(); |
| 48 m_pLinearized = NULL; | 98 m_pLinearized = NULL; |
| 49 m_dwFirstPageNo = 0; | 99 } |
| 50 m_dwXrefStartObjNum = 0; | 100 } |
| 51 m_bOwnFileRead = TRUE; | 101 static int32_t GetHeaderOffset(IFX_FileRead* pFile) { |
| 52 m_FileVersion = 0; | 102 FX_DWORD tag = FXDWORD_FROM_LSBFIRST(0x46445025); |
| 53 m_bForceUseSecurityHandler = FALSE; | 103 uint8_t buf[4]; |
| 54 } | 104 int32_t offset = 0; |
| 55 CPDF_Parser::~CPDF_Parser() | 105 while (1) { |
| 56 { | 106 if (!pFile->ReadBlock(buf, offset, 4)) { |
| 57 CloseParser(FALSE); | 107 return -1; |
| 58 } | 108 } |
| 59 FX_DWORD CPDF_Parser::GetLastObjNum() | 109 if (*(FX_DWORD*)buf == tag) { |
| 60 { | 110 return offset; |
| 61 FX_DWORD dwSize = m_CrossRef.GetSize(); | 111 } |
| 62 return dwSize ? dwSize - 1 : 0; | 112 offset++; |
| 63 } | 113 if (offset > 1024) { |
| 64 void CPDF_Parser::SetEncryptDictionary(CPDF_Dictionary* pDict) | 114 return -1; |
| 65 { | 115 } |
| 66 m_pEncryptDict = pDict; | 116 } |
| 67 } | 117 return -1; |
| 68 void CPDF_Parser::CloseParser(FX_BOOL bReParse) | 118 } |
| 69 { | 119 FX_DWORD CPDF_Parser::StartParse(const FX_CHAR* filename, FX_BOOL bReParse) { |
| 70 m_bVersionUpdated = FALSE; | 120 IFX_FileRead* pFileAccess = FX_CreateFileRead(filename); |
| 71 if (!bReParse) { | 121 if (!pFileAccess) { |
| 72 delete m_pDocument; | 122 return PDFPARSE_ERROR_FILE; |
| 73 m_pDocument = NULL; | 123 } |
| 74 } | 124 return StartParse(pFileAccess, bReParse); |
| 75 if (m_pTrailer) { | 125 } |
| 76 m_pTrailer->Release(); | 126 FX_DWORD CPDF_Parser::StartParse(const FX_WCHAR* filename, FX_BOOL bReParse) { |
| 77 m_pTrailer = NULL; | 127 IFX_FileRead* pFileAccess = FX_CreateFileRead(filename); |
| 78 } | 128 if (!pFileAccess) { |
| 79 ReleaseEncryptHandler(); | 129 return PDFPARSE_ERROR_FILE; |
| 80 SetEncryptDictionary(NULL); | 130 } |
| 81 if (m_bOwnFileRead && m_Syntax.m_pFileAccess) { | 131 return StartParse(pFileAccess, bReParse); |
| 82 m_Syntax.m_pFileAccess->Release(); | |
| 83 m_Syntax.m_pFileAccess = NULL; | |
| 84 } | |
| 85 FX_POSITION pos = m_ObjectStreamMap.GetStartPosition(); | |
| 86 while (pos) { | |
| 87 void* objnum; | |
| 88 CPDF_StreamAcc* pStream; | |
| 89 m_ObjectStreamMap.GetNextAssoc(pos, objnum, (void*&)pStream); | |
| 90 delete pStream; | |
| 91 } | |
| 92 m_ObjectStreamMap.RemoveAll(); | |
| 93 m_SortedOffset.RemoveAll(); | |
| 94 m_CrossRef.RemoveAll(); | |
| 95 m_V5Type.RemoveAll(); | |
| 96 m_ObjVersion.RemoveAll(); | |
| 97 int32_t iLen = m_Trailers.GetSize(); | |
| 98 for (int32_t i = 0; i < iLen; ++i) { | |
| 99 if (CPDF_Dictionary* trailer = m_Trailers.GetAt(i)) | |
| 100 trailer->Release(); | |
| 101 } | |
| 102 m_Trailers.RemoveAll(); | |
| 103 if (m_pLinearized) { | |
| 104 m_pLinearized->Release(); | |
| 105 m_pLinearized = NULL; | |
| 106 } | |
| 107 } | |
| 108 static int32_t GetHeaderOffset(IFX_FileRead* pFile) | |
| 109 { | |
| 110 FX_DWORD tag = FXDWORD_FROM_LSBFIRST(0x46445025); | |
| 111 uint8_t buf[4]; | |
| 112 int32_t offset = 0; | |
| 113 while (1) { | |
| 114 if (!pFile->ReadBlock(buf, offset, 4)) { | |
| 115 return -1; | |
| 116 } | |
| 117 if (*(FX_DWORD*)buf == tag) { | |
| 118 return offset; | |
| 119 } | |
| 120 offset ++; | |
| 121 if (offset > 1024) { | |
| 122 return -1; | |
| 123 } | |
| 124 } | |
| 125 return -1; | |
| 126 } | |
| 127 FX_DWORD CPDF_Parser::StartParse(const FX_CHAR* filename, FX_BOOL bReParse) | |
| 128 { | |
| 129 IFX_FileRead* pFileAccess = FX_CreateFileRead(filename); | |
| 130 if (!pFileAccess) { | |
| 131 return PDFPARSE_ERROR_FILE; | |
| 132 } | |
| 133 return StartParse(pFileAccess, bReParse); | |
| 134 } | |
| 135 FX_DWORD CPDF_Parser::StartParse(const FX_WCHAR* filename, FX_BOOL bReParse) | |
| 136 { | |
| 137 IFX_FileRead* pFileAccess = FX_CreateFileRead(filename); | |
| 138 if (!pFileAccess) { | |
| 139 return PDFPARSE_ERROR_FILE; | |
| 140 } | |
| 141 return StartParse(pFileAccess, bReParse); | |
| 142 } | 132 } |
| 143 CPDF_SecurityHandler* FPDF_CreateStandardSecurityHandler(); | 133 CPDF_SecurityHandler* FPDF_CreateStandardSecurityHandler(); |
| 144 CPDF_SecurityHandler* FPDF_CreatePubKeyHandler(void*); | 134 CPDF_SecurityHandler* FPDF_CreatePubKeyHandler(void*); |
| 145 FX_DWORD CPDF_Parser::StartParse(IFX_FileRead* pFileAccess, FX_BOOL bReParse, FX
_BOOL bOwnFileRead) | 135 FX_DWORD CPDF_Parser::StartParse(IFX_FileRead* pFileAccess, |
| 146 { | 136 FX_BOOL bReParse, |
| 147 CloseParser(bReParse); | 137 FX_BOOL bOwnFileRead) { |
| 148 m_bXRefStream = FALSE; | 138 CloseParser(bReParse); |
| 149 m_LastXRefOffset = 0; | 139 m_bXRefStream = FALSE; |
| 150 m_bOwnFileRead = bOwnFileRead; | 140 m_LastXRefOffset = 0; |
| 151 int32_t offset = GetHeaderOffset(pFileAccess); | 141 m_bOwnFileRead = bOwnFileRead; |
| 152 if (offset == -1) { | 142 int32_t offset = GetHeaderOffset(pFileAccess); |
| 153 if (bOwnFileRead && pFileAccess) { | 143 if (offset == -1) { |
| 154 pFileAccess->Release(); | 144 if (bOwnFileRead && pFileAccess) { |
| 155 } | 145 pFileAccess->Release(); |
| 146 } |
| 147 return PDFPARSE_ERROR_FORMAT; |
| 148 } |
| 149 m_Syntax.InitParser(pFileAccess, offset); |
| 150 uint8_t ch; |
| 151 if (!m_Syntax.GetCharAt(5, ch)) { |
| 152 return PDFPARSE_ERROR_FORMAT; |
| 153 } |
| 154 if (ch >= '0' && ch <= '9') { |
| 155 m_FileVersion = (ch - '0') * 10; |
| 156 } |
| 157 if (!m_Syntax.GetCharAt(7, ch)) { |
| 158 return PDFPARSE_ERROR_FORMAT; |
| 159 } |
| 160 if (ch >= '0' && ch <= '9') { |
| 161 m_FileVersion += ch - '0'; |
| 162 } |
| 163 if (m_Syntax.m_FileLen < m_Syntax.m_HeaderOffset + 9) { |
| 164 return PDFPARSE_ERROR_FORMAT; |
| 165 } |
| 166 m_Syntax.RestorePos(m_Syntax.m_FileLen - m_Syntax.m_HeaderOffset - 9); |
| 167 if (!bReParse) { |
| 168 m_pDocument = new CPDF_Document(this); |
| 169 } |
| 170 FX_BOOL bXRefRebuilt = FALSE; |
| 171 if (m_Syntax.SearchWord(FX_BSTRC("startxref"), TRUE, FALSE, 4096)) { |
| 172 FX_FILESIZE startxref_offset = m_Syntax.SavePos(); |
| 173 void* pResult = FXSYS_bsearch(&startxref_offset, m_SortedOffset.GetData(), |
| 174 m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), |
| 175 _CompareFileSize); |
| 176 if (pResult == NULL) { |
| 177 m_SortedOffset.Add(startxref_offset); |
| 178 } |
| 179 m_Syntax.GetKeyword(); |
| 180 FX_BOOL bNumber; |
| 181 CFX_ByteString xrefpos_str = m_Syntax.GetNextWord(bNumber); |
| 182 if (!bNumber) { |
| 183 return PDFPARSE_ERROR_FORMAT; |
| 184 } |
| 185 m_LastXRefOffset = (FX_FILESIZE)FXSYS_atoi64(xrefpos_str); |
| 186 if (!LoadAllCrossRefV4(m_LastXRefOffset) && |
| 187 !LoadAllCrossRefV5(m_LastXRefOffset)) { |
| 188 if (!RebuildCrossRef()) { |
| 156 return PDFPARSE_ERROR_FORMAT; | 189 return PDFPARSE_ERROR_FORMAT; |
| 157 } | 190 } |
| 158 m_Syntax.InitParser(pFileAccess, offset); | 191 bXRefRebuilt = TRUE; |
| 159 uint8_t ch; | 192 m_LastXRefOffset = 0; |
| 160 if (!m_Syntax.GetCharAt(5, ch)) { | 193 } |
| 161 return PDFPARSE_ERROR_FORMAT; | 194 } else { |
| 162 } | 195 if (!RebuildCrossRef()) { |
| 163 if (ch >= '0' && ch <= '9') { | 196 return PDFPARSE_ERROR_FORMAT; |
| 164 m_FileVersion = (ch - '0') * 10; | 197 } |
| 165 } | 198 bXRefRebuilt = TRUE; |
| 166 if (!m_Syntax.GetCharAt(7, ch)) { | 199 } |
| 167 return PDFPARSE_ERROR_FORMAT; | 200 FX_DWORD dwRet = SetEncryptHandler(); |
| 168 } | 201 if (dwRet != PDFPARSE_ERROR_SUCCESS) { |
| 169 if (ch >= '0' && ch <= '9') { | 202 return dwRet; |
| 170 m_FileVersion += ch - '0'; | 203 } |
| 171 } | 204 m_pDocument->LoadDoc(); |
| 172 if (m_Syntax.m_FileLen < m_Syntax.m_HeaderOffset + 9) { | 205 if (m_pDocument->GetRoot() == NULL || m_pDocument->GetPageCount() == 0) { |
| 173 return PDFPARSE_ERROR_FORMAT; | 206 if (bXRefRebuilt) { |
| 174 } | 207 return PDFPARSE_ERROR_FORMAT; |
| 175 m_Syntax.RestorePos(m_Syntax.m_FileLen - m_Syntax.m_HeaderOffset - 9); | 208 } |
| 176 if (!bReParse) { | 209 ReleaseEncryptHandler(); |
| 177 m_pDocument = new CPDF_Document(this); | 210 if (!RebuildCrossRef()) { |
| 178 } | 211 return PDFPARSE_ERROR_FORMAT; |
| 179 FX_BOOL bXRefRebuilt = FALSE; | 212 } |
| 180 if (m_Syntax.SearchWord(FX_BSTRC("startxref"), TRUE, FALSE, 4096)) { | 213 dwRet = SetEncryptHandler(); |
| 181 FX_FILESIZE startxref_offset = m_Syntax.SavePos(); | 214 if (dwRet != PDFPARSE_ERROR_SUCCESS) { |
| 182 void* pResult = FXSYS_bsearch(&startxref_offset, m_SortedOffset.GetData(
), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); | 215 return dwRet; |
| 216 } |
| 217 m_pDocument->LoadDoc(); |
| 218 if (m_pDocument->GetRoot() == NULL) { |
| 219 return PDFPARSE_ERROR_FORMAT; |
| 220 } |
| 221 } |
| 222 FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(), |
| 223 sizeof(FX_FILESIZE), _CompareFileSize); |
| 224 FX_DWORD RootObjNum = GetRootObjNum(); |
| 225 if (RootObjNum == 0) { |
| 226 ReleaseEncryptHandler(); |
| 227 RebuildCrossRef(); |
| 228 RootObjNum = GetRootObjNum(); |
| 229 if (RootObjNum == 0) { |
| 230 return PDFPARSE_ERROR_FORMAT; |
| 231 } |
| 232 dwRet = SetEncryptHandler(); |
| 233 if (dwRet != PDFPARSE_ERROR_SUCCESS) { |
| 234 return dwRet; |
| 235 } |
| 236 } |
| 237 if (m_pSecurityHandler && !m_pSecurityHandler->IsMetadataEncrypted()) { |
| 238 CPDF_Reference* pMetadata = |
| 239 (CPDF_Reference*)m_pDocument->GetRoot()->GetElement( |
| 240 FX_BSTRC("Metadata")); |
| 241 if (pMetadata && pMetadata->GetType() == PDFOBJ_REFERENCE) { |
| 242 m_Syntax.m_MetadataObjnum = pMetadata->GetRefObjNum(); |
| 243 } |
| 244 } |
| 245 return PDFPARSE_ERROR_SUCCESS; |
| 246 } |
| 247 FX_DWORD CPDF_Parser::SetEncryptHandler() { |
| 248 ReleaseEncryptHandler(); |
| 249 SetEncryptDictionary(NULL); |
| 250 if (m_pTrailer == NULL) { |
| 251 return PDFPARSE_ERROR_FORMAT; |
| 252 } |
| 253 CPDF_Object* pEncryptObj = m_pTrailer->GetElement(FX_BSTRC("Encrypt")); |
| 254 if (pEncryptObj) { |
| 255 if (pEncryptObj->GetType() == PDFOBJ_DICTIONARY) { |
| 256 SetEncryptDictionary((CPDF_Dictionary*)pEncryptObj); |
| 257 } else if (pEncryptObj->GetType() == PDFOBJ_REFERENCE) { |
| 258 pEncryptObj = m_pDocument->GetIndirectObject( |
| 259 ((CPDF_Reference*)pEncryptObj)->GetRefObjNum()); |
| 260 if (pEncryptObj) { |
| 261 SetEncryptDictionary(pEncryptObj->GetDict()); |
| 262 } |
| 263 } |
| 264 } |
| 265 if (m_bForceUseSecurityHandler) { |
| 266 FX_DWORD err = PDFPARSE_ERROR_HANDLER; |
| 267 if (m_pSecurityHandler == NULL) { |
| 268 return PDFPARSE_ERROR_HANDLER; |
| 269 } |
| 270 if (!m_pSecurityHandler->OnInit(this, m_pEncryptDict)) { |
| 271 return err; |
| 272 } |
| 273 CPDF_CryptoHandler* pCryptoHandler = |
| 274 m_pSecurityHandler->CreateCryptoHandler(); |
| 275 if (!pCryptoHandler->Init(m_pEncryptDict, m_pSecurityHandler)) { |
| 276 delete pCryptoHandler; |
| 277 pCryptoHandler = NULL; |
| 278 return PDFPARSE_ERROR_HANDLER; |
| 279 } |
| 280 m_Syntax.SetEncrypt(pCryptoHandler); |
| 281 } else if (m_pEncryptDict) { |
| 282 CFX_ByteString filter = m_pEncryptDict->GetString(FX_BSTRC("Filter")); |
| 283 CPDF_SecurityHandler* pSecurityHandler = NULL; |
| 284 FX_DWORD err = PDFPARSE_ERROR_HANDLER; |
| 285 if (filter == FX_BSTRC("Standard")) { |
| 286 pSecurityHandler = FPDF_CreateStandardSecurityHandler(); |
| 287 err = PDFPARSE_ERROR_PASSWORD; |
| 288 } |
| 289 if (pSecurityHandler == NULL) { |
| 290 return PDFPARSE_ERROR_HANDLER; |
| 291 } |
| 292 if (!pSecurityHandler->OnInit(this, m_pEncryptDict)) { |
| 293 delete pSecurityHandler; |
| 294 pSecurityHandler = NULL; |
| 295 return err; |
| 296 } |
| 297 m_pSecurityHandler = pSecurityHandler; |
| 298 CPDF_CryptoHandler* pCryptoHandler = |
| 299 pSecurityHandler->CreateCryptoHandler(); |
| 300 if (!pCryptoHandler->Init(m_pEncryptDict, m_pSecurityHandler)) { |
| 301 delete pCryptoHandler; |
| 302 pCryptoHandler = NULL; |
| 303 return PDFPARSE_ERROR_HANDLER; |
| 304 } |
| 305 m_Syntax.SetEncrypt(pCryptoHandler); |
| 306 } |
| 307 return PDFPARSE_ERROR_SUCCESS; |
| 308 } |
| 309 void CPDF_Parser::ReleaseEncryptHandler() { |
| 310 delete m_Syntax.m_pCryptoHandler; |
| 311 m_Syntax.m_pCryptoHandler = NULL; |
| 312 if (!m_bForceUseSecurityHandler) { |
| 313 delete m_pSecurityHandler; |
| 314 m_pSecurityHandler = NULL; |
| 315 } |
| 316 } |
| 317 FX_FILESIZE CPDF_Parser::GetObjectOffset(FX_DWORD objnum) { |
| 318 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) { |
| 319 return 0; |
| 320 } |
| 321 if (m_V5Type[objnum] == 1) { |
| 322 return m_CrossRef[objnum]; |
| 323 } |
| 324 if (m_V5Type[objnum] == 2) { |
| 325 return m_CrossRef[(int32_t)m_CrossRef[objnum]]; |
| 326 } |
| 327 return 0; |
| 328 } |
| 329 static int32_t GetDirectInteger(CPDF_Dictionary* pDict, |
| 330 const CFX_ByteStringC& key) { |
| 331 CPDF_Object* pObj = pDict->GetElement(key); |
| 332 if (pObj == NULL) { |
| 333 return 0; |
| 334 } |
| 335 if (pObj->GetType() == PDFOBJ_NUMBER) { |
| 336 return ((CPDF_Number*)pObj)->GetInteger(); |
| 337 } |
| 338 return 0; |
| 339 } |
| 340 static FX_BOOL CheckDirectType(CPDF_Dictionary* pDict, |
| 341 const CFX_ByteStringC& key, |
| 342 int32_t iType) { |
| 343 CPDF_Object* pObj = pDict->GetElement(key); |
| 344 if (!pObj) { |
| 345 return TRUE; |
| 346 } |
| 347 return pObj->GetType() == iType; |
| 348 } |
| 349 FX_BOOL CPDF_Parser::LoadAllCrossRefV4(FX_FILESIZE xrefpos) { |
| 350 if (!LoadCrossRefV4(xrefpos, 0, TRUE, FALSE)) { |
| 351 return FALSE; |
| 352 } |
| 353 m_pTrailer = LoadTrailerV4(); |
| 354 if (m_pTrailer == NULL) { |
| 355 return FALSE; |
| 356 } |
| 357 int32_t xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size")); |
| 358 if (xrefsize <= 0 || xrefsize > (1 << 20)) { |
| 359 return FALSE; |
| 360 } |
| 361 m_CrossRef.SetSize(xrefsize); |
| 362 m_V5Type.SetSize(xrefsize); |
| 363 CFX_FileSizeArray CrossRefList, XRefStreamList; |
| 364 CrossRefList.Add(xrefpos); |
| 365 XRefStreamList.Add(GetDirectInteger(m_pTrailer, FX_BSTRC("XRefStm"))); |
| 366 if (!CheckDirectType(m_pTrailer, FX_BSTRC("Prev"), PDFOBJ_NUMBER)) { |
| 367 return FALSE; |
| 368 } |
| 369 FX_FILESIZE newxrefpos = GetDirectInteger(m_pTrailer, FX_BSTRC("Prev")); |
| 370 if (newxrefpos == xrefpos) { |
| 371 return FALSE; |
| 372 } |
| 373 xrefpos = newxrefpos; |
| 374 while (xrefpos) { |
| 375 CrossRefList.InsertAt(0, xrefpos); |
| 376 LoadCrossRefV4(xrefpos, 0, TRUE, FALSE); |
| 377 CPDF_Dictionary* pDict = LoadTrailerV4(); |
| 378 if (pDict == NULL) { |
| 379 return FALSE; |
| 380 } |
| 381 if (!CheckDirectType(pDict, FX_BSTRC("Prev"), PDFOBJ_NUMBER)) { |
| 382 pDict->Release(); |
| 383 return FALSE; |
| 384 } |
| 385 newxrefpos = GetDirectInteger(pDict, FX_BSTRC("Prev")); |
| 386 if (newxrefpos == xrefpos) { |
| 387 pDict->Release(); |
| 388 return FALSE; |
| 389 } |
| 390 xrefpos = newxrefpos; |
| 391 XRefStreamList.InsertAt(0, pDict->GetInteger(FX_BSTRC("XRefStm"))); |
| 392 m_Trailers.Add(pDict); |
| 393 } |
| 394 for (int32_t i = 0; i < CrossRefList.GetSize(); i++) |
| 395 if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE, i == 0)) { |
| 396 return FALSE; |
| 397 } |
| 398 return TRUE; |
| 399 } |
| 400 FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV4(FX_FILESIZE xrefpos, |
| 401 FX_DWORD dwObjCount) { |
| 402 if (!LoadLinearizedCrossRefV4(xrefpos, dwObjCount)) { |
| 403 return FALSE; |
| 404 } |
| 405 m_pTrailer = LoadTrailerV4(); |
| 406 if (m_pTrailer == NULL) { |
| 407 return FALSE; |
| 408 } |
| 409 int32_t xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size")); |
| 410 if (xrefsize == 0) { |
| 411 return FALSE; |
| 412 } |
| 413 CFX_FileSizeArray CrossRefList, XRefStreamList; |
| 414 CrossRefList.Add(xrefpos); |
| 415 XRefStreamList.Add(GetDirectInteger(m_pTrailer, FX_BSTRC("XRefStm"))); |
| 416 xrefpos = GetDirectInteger(m_pTrailer, FX_BSTRC("Prev")); |
| 417 while (xrefpos) { |
| 418 CrossRefList.InsertAt(0, xrefpos); |
| 419 LoadCrossRefV4(xrefpos, 0, TRUE, FALSE); |
| 420 CPDF_Dictionary* pDict = LoadTrailerV4(); |
| 421 if (pDict == NULL) { |
| 422 return FALSE; |
| 423 } |
| 424 xrefpos = GetDirectInteger(pDict, FX_BSTRC("Prev")); |
| 425 XRefStreamList.InsertAt(0, pDict->GetInteger(FX_BSTRC("XRefStm"))); |
| 426 m_Trailers.Add(pDict); |
| 427 } |
| 428 for (int32_t i = 1; i < CrossRefList.GetSize(); i++) |
| 429 if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE, i == 0)) { |
| 430 return FALSE; |
| 431 } |
| 432 return TRUE; |
| 433 } |
| 434 FX_BOOL CPDF_Parser::LoadLinearizedCrossRefV4(FX_FILESIZE pos, |
| 435 FX_DWORD dwObjCount) { |
| 436 FX_FILESIZE dwStartPos = pos - m_Syntax.m_HeaderOffset; |
| 437 m_Syntax.RestorePos(dwStartPos); |
| 438 void* pResult = |
| 439 FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), |
| 440 sizeof(FX_FILESIZE), _CompareFileSize); |
| 441 if (pResult == NULL) { |
| 442 m_SortedOffset.Add(pos); |
| 443 } |
| 444 FX_DWORD start_objnum = 0; |
| 445 FX_DWORD count = dwObjCount; |
| 446 FX_FILESIZE SavedPos = m_Syntax.SavePos(); |
| 447 int32_t recordsize = 20; |
| 448 char* pBuf = FX_Alloc(char, 1024 * recordsize + 1); |
| 449 pBuf[1024 * recordsize] = '\0'; |
| 450 int32_t nBlocks = count / 1024 + 1; |
| 451 for (int32_t block = 0; block < nBlocks; block++) { |
| 452 int32_t block_size = block == nBlocks - 1 ? count % 1024 : 1024; |
| 453 FX_DWORD dwReadSize = block_size * recordsize; |
| 454 if ((FX_FILESIZE)(dwStartPos + dwReadSize) > m_Syntax.m_FileLen) { |
| 455 FX_Free(pBuf); |
| 456 return FALSE; |
| 457 } |
| 458 if (!m_Syntax.ReadBlock((uint8_t*)pBuf, dwReadSize)) { |
| 459 FX_Free(pBuf); |
| 460 return FALSE; |
| 461 } |
| 462 for (int32_t i = 0; i < block_size; i++) { |
| 463 FX_DWORD objnum = start_objnum + block * 1024 + i; |
| 464 char* pEntry = pBuf + i * recordsize; |
| 465 if (pEntry[17] == 'f') { |
| 466 m_CrossRef.SetAtGrow(objnum, 0); |
| 467 m_V5Type.SetAtGrow(objnum, 0); |
| 468 } else { |
| 469 int32_t offset = FXSYS_atoi(pEntry); |
| 470 if (offset == 0) { |
| 471 for (int32_t c = 0; c < 10; c++) { |
| 472 if (pEntry[c] < '0' || pEntry[c] > '9') { |
| 473 FX_Free(pBuf); |
| 474 return FALSE; |
| 475 } |
| 476 } |
| 477 } |
| 478 m_CrossRef.SetAtGrow(objnum, offset); |
| 479 int32_t version = FXSYS_atoi(pEntry + 11); |
| 480 if (version >= 1) { |
| 481 m_bVersionUpdated = TRUE; |
| 482 } |
| 483 m_ObjVersion.SetAtGrow(objnum, version); |
| 484 if (m_CrossRef[objnum] < m_Syntax.m_FileLen) { |
| 485 void* pResult = FXSYS_bsearch( |
| 486 &m_CrossRef[objnum], m_SortedOffset.GetData(), |
| 487 m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); |
| 488 if (pResult == NULL) { |
| 489 m_SortedOffset.Add(m_CrossRef[objnum]); |
| 490 } |
| 491 } |
| 492 m_V5Type.SetAtGrow(objnum, 1); |
| 493 } |
| 494 } |
| 495 } |
| 496 FX_Free(pBuf); |
| 497 m_Syntax.RestorePos(SavedPos + count * recordsize); |
| 498 return TRUE; |
| 499 } |
| 500 FX_BOOL CPDF_Parser::LoadCrossRefV4(FX_FILESIZE pos, |
| 501 FX_FILESIZE streampos, |
| 502 FX_BOOL bSkip, |
| 503 FX_BOOL bFirst) { |
| 504 m_Syntax.RestorePos(pos); |
| 505 if (m_Syntax.GetKeyword() != FX_BSTRC("xref")) { |
| 506 return FALSE; |
| 507 } |
| 508 void* pResult = |
| 509 FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), |
| 510 sizeof(FX_FILESIZE), _CompareFileSize); |
| 511 if (pResult == NULL) { |
| 512 m_SortedOffset.Add(pos); |
| 513 } |
| 514 if (streampos) { |
| 515 void* pResult = FXSYS_bsearch(&streampos, m_SortedOffset.GetData(), |
| 516 m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), |
| 517 _CompareFileSize); |
| 518 if (pResult == NULL) { |
| 519 m_SortedOffset.Add(streampos); |
| 520 } |
| 521 } |
| 522 while (1) { |
| 523 FX_FILESIZE SavedPos = m_Syntax.SavePos(); |
| 524 FX_BOOL bIsNumber; |
| 525 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); |
| 526 if (word.IsEmpty()) { |
| 527 return FALSE; |
| 528 } |
| 529 if (!bIsNumber) { |
| 530 m_Syntax.RestorePos(SavedPos); |
| 531 break; |
| 532 } |
| 533 FX_DWORD start_objnum = FXSYS_atoi(word); |
| 534 if (start_objnum >= (1 << 20)) { |
| 535 return FALSE; |
| 536 } |
| 537 FX_DWORD count = m_Syntax.GetDirectNum(); |
| 538 m_Syntax.ToNextWord(); |
| 539 SavedPos = m_Syntax.SavePos(); |
| 540 FX_BOOL bFirstItem = FALSE; |
| 541 int32_t recordsize = 20; |
| 542 if (bFirst) { |
| 543 bFirstItem = TRUE; |
| 544 } |
| 545 m_dwXrefStartObjNum = start_objnum; |
| 546 if (!bSkip) { |
| 547 char* pBuf = FX_Alloc(char, 1024 * recordsize + 1); |
| 548 pBuf[1024 * recordsize] = '\0'; |
| 549 int32_t nBlocks = count / 1024 + 1; |
| 550 FX_BOOL bFirstBlock = TRUE; |
| 551 for (int32_t block = 0; block < nBlocks; block++) { |
| 552 int32_t block_size = block == nBlocks - 1 ? count % 1024 : 1024; |
| 553 m_Syntax.ReadBlock((uint8_t*)pBuf, block_size * recordsize); |
| 554 for (int32_t i = 0; i < block_size; i++) { |
| 555 FX_DWORD objnum = start_objnum + block * 1024 + i; |
| 556 char* pEntry = pBuf + i * recordsize; |
| 557 if (pEntry[17] == 'f') { |
| 558 if (bFirstItem) { |
| 559 objnum = 0; |
| 560 bFirstItem = FALSE; |
| 561 } |
| 562 if (bFirstBlock) { |
| 563 FX_FILESIZE offset = (FX_FILESIZE)FXSYS_atoi64(pEntry); |
| 564 int32_t version = FXSYS_atoi(pEntry + 11); |
| 565 if (offset == 0 && version == 65535 && start_objnum != 0) { |
| 566 start_objnum--; |
| 567 objnum = 0; |
| 568 } |
| 569 } |
| 570 m_CrossRef.SetAtGrow(objnum, 0); |
| 571 m_V5Type.SetAtGrow(objnum, 0); |
| 572 } else { |
| 573 FX_FILESIZE offset = (FX_FILESIZE)FXSYS_atoi64(pEntry); |
| 574 if (offset == 0) { |
| 575 for (int32_t c = 0; c < 10; c++) { |
| 576 if (pEntry[c] < '0' || pEntry[c] > '9') { |
| 577 FX_Free(pBuf); |
| 578 return FALSE; |
| 579 } |
| 580 } |
| 581 } |
| 582 m_CrossRef.SetAtGrow(objnum, offset); |
| 583 int32_t version = FXSYS_atoi(pEntry + 11); |
| 584 if (version >= 1) { |
| 585 m_bVersionUpdated = TRUE; |
| 586 } |
| 587 m_ObjVersion.SetAtGrow(objnum, version); |
| 588 if (m_CrossRef[objnum] < m_Syntax.m_FileLen) { |
| 589 void* pResult = |
| 590 FXSYS_bsearch(&m_CrossRef[objnum], m_SortedOffset.GetData(), |
| 591 m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), |
| 592 _CompareFileSize); |
| 593 if (pResult == NULL) { |
| 594 m_SortedOffset.Add(m_CrossRef[objnum]); |
| 595 } |
| 596 } |
| 597 m_V5Type.SetAtGrow(objnum, 1); |
| 598 } |
| 599 if (bFirstBlock) { |
| 600 bFirstBlock = FALSE; |
| 601 } |
| 602 } |
| 603 } |
| 604 FX_Free(pBuf); |
| 605 } |
| 606 m_Syntax.RestorePos(SavedPos + count * recordsize); |
| 607 } |
| 608 if (streampos) |
| 609 if (!LoadCrossRefV5(streampos, streampos, FALSE)) { |
| 610 return FALSE; |
| 611 } |
| 612 return TRUE; |
| 613 } |
| 614 FX_BOOL CPDF_Parser::LoadAllCrossRefV5(FX_FILESIZE xrefpos) { |
| 615 if (!LoadCrossRefV5(xrefpos, xrefpos, TRUE)) { |
| 616 return FALSE; |
| 617 } |
| 618 while (xrefpos) |
| 619 if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) { |
| 620 return FALSE; |
| 621 } |
| 622 m_ObjectStreamMap.InitHashTable(101, FALSE); |
| 623 m_bXRefStream = TRUE; |
| 624 return TRUE; |
| 625 } |
| 626 FX_BOOL CPDF_Parser::RebuildCrossRef() { |
| 627 m_CrossRef.RemoveAll(); |
| 628 m_V5Type.RemoveAll(); |
| 629 m_SortedOffset.RemoveAll(); |
| 630 m_ObjVersion.RemoveAll(); |
| 631 if (m_pTrailer) { |
| 632 m_pTrailer->Release(); |
| 633 m_pTrailer = NULL; |
| 634 } |
| 635 int32_t status = 0; |
| 636 int32_t inside_index = 0; |
| 637 FX_DWORD objnum = 0, gennum = 0; |
| 638 int32_t depth = 0; |
| 639 uint8_t* buffer = FX_Alloc(uint8_t, 4096); |
| 640 FX_FILESIZE pos = m_Syntax.m_HeaderOffset; |
| 641 FX_FILESIZE start_pos = 0, start_pos1 = 0; |
| 642 FX_FILESIZE last_obj = -1, last_xref = -1, last_trailer = -1; |
| 643 while (pos < m_Syntax.m_FileLen) { |
| 644 FX_BOOL bOverFlow = FALSE; |
| 645 FX_DWORD size = (FX_DWORD)(m_Syntax.m_FileLen - pos); |
| 646 if (size > 4096) { |
| 647 size = 4096; |
| 648 } |
| 649 if (!m_Syntax.m_pFileAccess->ReadBlock(buffer, pos, size)) { |
| 650 break; |
| 651 } |
| 652 for (FX_DWORD i = 0; i < size; i++) { |
| 653 uint8_t byte = buffer[i]; |
| 654 switch (status) { |
| 655 case 0: |
| 656 if (PDF_CharType[byte] == 'W') { |
| 657 status = 1; |
| 658 } |
| 659 if (byte <= '9' && byte >= '0') { |
| 660 --i; |
| 661 status = 1; |
| 662 } |
| 663 if (byte == '%') { |
| 664 inside_index = 0; |
| 665 status = 9; |
| 666 } |
| 667 if (byte == '(') { |
| 668 status = 10; |
| 669 depth = 1; |
| 670 } |
| 671 if (byte == '<') { |
| 672 inside_index = 1; |
| 673 status = 11; |
| 674 } |
| 675 if (byte == '\\') { |
| 676 status = 13; |
| 677 } |
| 678 if (byte == 't') { |
| 679 status = 7; |
| 680 inside_index = 1; |
| 681 } |
| 682 break; |
| 683 case 1: |
| 684 if (PDF_CharType[byte] == 'W') { |
| 685 break; |
| 686 } else if (byte <= '9' && byte >= '0') { |
| 687 start_pos = pos + i; |
| 688 status = 2; |
| 689 objnum = byte - '0'; |
| 690 } else if (byte == 't') { |
| 691 status = 7; |
| 692 inside_index = 1; |
| 693 } else if (byte == 'x') { |
| 694 status = 8; |
| 695 inside_index = 1; |
| 696 } else { |
| 697 --i; |
| 698 status = 0; |
| 699 } |
| 700 break; |
| 701 case 2: |
| 702 if (byte <= '9' && byte >= '0') { |
| 703 objnum = objnum * 10 + byte - '0'; |
| 704 break; |
| 705 } else if (PDF_CharType[byte] == 'W') { |
| 706 status = 3; |
| 707 } else { |
| 708 --i; |
| 709 status = 14; |
| 710 inside_index = 0; |
| 711 } |
| 712 break; |
| 713 case 3: |
| 714 if (byte <= '9' && byte >= '0') { |
| 715 start_pos1 = pos + i; |
| 716 status = 4; |
| 717 gennum = byte - '0'; |
| 718 } else if (PDF_CharType[byte] == 'W') { |
| 719 break; |
| 720 } else if (byte == 't') { |
| 721 status = 7; |
| 722 inside_index = 1; |
| 723 } else { |
| 724 --i; |
| 725 status = 0; |
| 726 } |
| 727 break; |
| 728 case 4: |
| 729 if (byte <= '9' && byte >= '0') { |
| 730 gennum = gennum * 10 + byte - '0'; |
| 731 break; |
| 732 } else if (PDF_CharType[byte] == 'W') { |
| 733 status = 5; |
| 734 } else { |
| 735 --i; |
| 736 status = 0; |
| 737 } |
| 738 break; |
| 739 case 5: |
| 740 if (byte == 'o') { |
| 741 status = 6; |
| 742 inside_index = 1; |
| 743 } else if (PDF_CharType[byte] == 'W') { |
| 744 break; |
| 745 } else if (byte <= '9' && byte >= '0') { |
| 746 objnum = gennum; |
| 747 gennum = byte - '0'; |
| 748 start_pos = start_pos1; |
| 749 start_pos1 = pos + i; |
| 750 status = 4; |
| 751 } else if (byte == 't') { |
| 752 status = 7; |
| 753 inside_index = 1; |
| 754 } else { |
| 755 --i; |
| 756 status = 0; |
| 757 } |
| 758 break; |
| 759 case 6: |
| 760 switch (inside_index) { |
| 761 case 1: |
| 762 if (byte != 'b') { |
| 763 --i; |
| 764 status = 0; |
| 765 } else { |
| 766 inside_index++; |
| 767 } |
| 768 break; |
| 769 case 2: |
| 770 if (byte != 'j') { |
| 771 --i; |
| 772 status = 0; |
| 773 } else { |
| 774 inside_index++; |
| 775 } |
| 776 break; |
| 777 case 3: |
| 778 if (PDF_CharType[byte] == 'W' || PDF_CharType[byte] == 'D') { |
| 779 if (objnum > 0x1000000) { |
| 780 status = 0; |
| 781 break; |
| 782 } |
| 783 FX_FILESIZE obj_pos = start_pos - m_Syntax.m_HeaderOffset; |
| 784 last_obj = start_pos; |
| 785 void* pResult = |
| 786 FXSYS_bsearch(&obj_pos, m_SortedOffset.GetData(), |
| 787 m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), |
| 788 _CompareFileSize); |
| 789 if (pResult == NULL) { |
| 790 m_SortedOffset.Add(obj_pos); |
| 791 } |
| 792 FX_FILESIZE obj_end = 0; |
| 793 CPDF_Object* pObject = ParseIndirectObjectAtByStrict( |
| 794 m_pDocument, obj_pos, objnum, NULL, &obj_end); |
| 795 if (pObject) { |
| 796 int iType = pObject->GetType(); |
| 797 if (iType == PDFOBJ_STREAM) { |
| 798 CPDF_Stream* pStream = (CPDF_Stream*)pObject; |
| 799 CPDF_Dictionary* pDict = pStream->GetDict(); |
| 800 if (pDict) { |
| 801 if (pDict->KeyExist(FX_BSTRC("Type"))) { |
| 802 CFX_ByteString bsValue = |
| 803 pDict->GetString(FX_BSTRC("Type")); |
| 804 if (bsValue == FX_BSTRC("XRef") && |
| 805 pDict->KeyExist(FX_BSTRC("Size"))) { |
| 806 CPDF_Object* pRoot = |
| 807 pDict->GetElement(FX_BSTRC("Root")); |
| 808 if (pRoot && pRoot->GetDict() && |
| 809 pRoot->GetDict()->GetElement(FX_BSTRC("Pages"))) { |
| 810 if (m_pTrailer) { |
| 811 m_pTrailer->Release(); |
| 812 } |
| 813 m_pTrailer = (CPDF_Dictionary*)pDict->Clone(); |
| 814 } |
| 815 } |
| 816 } |
| 817 } |
| 818 } |
| 819 } |
| 820 FX_FILESIZE offset = 0; |
| 821 m_Syntax.RestorePos(obj_pos); |
| 822 offset = m_Syntax.FindTag(FX_BSTRC("obj"), 0); |
| 823 if (offset == -1) { |
| 824 offset = 0; |
| 825 } else { |
| 826 offset += 3; |
| 827 } |
| 828 FX_FILESIZE nLen = obj_end - obj_pos - offset; |
| 829 if ((FX_DWORD)nLen > size - i) { |
| 830 pos = obj_end + m_Syntax.m_HeaderOffset; |
| 831 bOverFlow = TRUE; |
| 832 } else { |
| 833 i += (FX_DWORD)nLen; |
| 834 } |
| 835 if (m_CrossRef.GetSize() > (int32_t)objnum && |
| 836 m_CrossRef[objnum]) { |
| 837 if (pObject) { |
| 838 FX_DWORD oldgen = m_ObjVersion.GetAt(objnum); |
| 839 m_CrossRef[objnum] = obj_pos; |
| 840 m_ObjVersion.SetAt(objnum, (int16_t)gennum); |
| 841 if (oldgen != gennum) { |
| 842 m_bVersionUpdated = TRUE; |
| 843 } |
| 844 } |
| 845 } else { |
| 846 m_CrossRef.SetAtGrow(objnum, obj_pos); |
| 847 m_V5Type.SetAtGrow(objnum, 1); |
| 848 m_ObjVersion.SetAtGrow(objnum, (int16_t)gennum); |
| 849 } |
| 850 if (pObject) { |
| 851 pObject->Release(); |
| 852 } |
| 853 } |
| 854 --i; |
| 855 status = 0; |
| 856 break; |
| 857 } |
| 858 break; |
| 859 case 7: |
| 860 if (inside_index == 7) { |
| 861 if (PDF_CharType[byte] == 'W' || PDF_CharType[byte] == 'D') { |
| 862 last_trailer = pos + i - 7; |
| 863 m_Syntax.RestorePos(pos + i - m_Syntax.m_HeaderOffset); |
| 864 CPDF_Object* pObj = m_Syntax.GetObject(m_pDocument, 0, 0, 0); |
| 865 if (pObj) { |
| 866 if (pObj->GetType() != PDFOBJ_DICTIONARY && |
| 867 pObj->GetType() != PDFOBJ_STREAM) { |
| 868 pObj->Release(); |
| 869 } else { |
| 870 CPDF_Dictionary* pTrailer = NULL; |
| 871 if (pObj->GetType() == PDFOBJ_STREAM) { |
| 872 pTrailer = ((CPDF_Stream*)pObj)->GetDict(); |
| 873 } else { |
| 874 pTrailer = (CPDF_Dictionary*)pObj; |
| 875 } |
| 876 if (pTrailer) { |
| 877 if (m_pTrailer) { |
| 878 CPDF_Object* pRoot = |
| 879 pTrailer->GetElement(FX_BSTRC("Root")); |
| 880 if (pRoot == NULL || |
| 881 (pRoot->GetType() == PDFOBJ_REFERENCE && |
| 882 (FX_DWORD)m_CrossRef.GetSize() > |
| 883 ((CPDF_Reference*)pRoot)->GetRefObjNum() && |
| 884 m_CrossRef.GetAt(((CPDF_Reference*)pRoot) |
| 885 ->GetRefObjNum()) != 0)) { |
| 886 FX_POSITION pos = pTrailer->GetStartPos(); |
| 887 while (pos) { |
| 888 CFX_ByteString key; |
| 889 CPDF_Object* pObj = |
| 890 pTrailer->GetNextElement(pos, key); |
| 891 m_pTrailer->SetAt(key, pObj->Clone(), m_pDocument); |
| 892 } |
| 893 pObj->Release(); |
| 894 } else { |
| 895 pObj->Release(); |
| 896 } |
| 897 } else { |
| 898 if (pObj->GetType() == PDFOBJ_STREAM) { |
| 899 m_pTrailer = (CPDF_Dictionary*)pTrailer->Clone(); |
| 900 pObj->Release(); |
| 901 } else { |
| 902 m_pTrailer = pTrailer; |
| 903 } |
| 904 FX_FILESIZE dwSavePos = m_Syntax.SavePos(); |
| 905 CFX_ByteString strWord = m_Syntax.GetKeyword(); |
| 906 if (!strWord.Compare(FX_BSTRC("startxref"))) { |
| 907 FX_BOOL bNumber = FALSE; |
| 908 CFX_ByteString bsOffset = m_Syntax.GetNextWord(bNumber); |
| 909 if (bNumber) { |
| 910 m_LastXRefOffset = FXSYS_atoi(bsOffset); |
| 911 } |
| 912 } |
| 913 m_Syntax.RestorePos(dwSavePos); |
| 914 } |
| 915 } else { |
| 916 pObj->Release(); |
| 917 } |
| 918 } |
| 919 } |
| 920 } |
| 921 --i; |
| 922 status = 0; |
| 923 } else if (byte == "trailer"[inside_index]) { |
| 924 inside_index++; |
| 925 } else { |
| 926 --i; |
| 927 status = 0; |
| 928 } |
| 929 break; |
| 930 case 8: |
| 931 if (inside_index == 4) { |
| 932 last_xref = pos + i - 4; |
| 933 status = 1; |
| 934 } else if (byte == "xref"[inside_index]) { |
| 935 inside_index++; |
| 936 } else { |
| 937 --i; |
| 938 status = 0; |
| 939 } |
| 940 break; |
| 941 case 9: |
| 942 if (byte == '\r' || byte == '\n') { |
| 943 status = 0; |
| 944 } |
| 945 break; |
| 946 case 10: |
| 947 if (byte == ')') { |
| 948 if (depth > 0) { |
| 949 depth--; |
| 950 } |
| 951 } else if (byte == '(') { |
| 952 depth++; |
| 953 } |
| 954 if (!depth) { |
| 955 status = 0; |
| 956 } |
| 957 break; |
| 958 case 11: |
| 959 if (byte == '<' && inside_index == 1) { |
| 960 status = 12; |
| 961 } else if (byte == '>') { |
| 962 status = 0; |
| 963 } |
| 964 inside_index = 0; |
| 965 break; |
| 966 case 12: |
| 967 --i; |
| 968 status = 0; |
| 969 break; |
| 970 case 13: |
| 971 if (PDF_CharType[byte] == 'D' || PDF_CharType[byte] == 'W') { |
| 972 --i; |
| 973 status = 0; |
| 974 } |
| 975 break; |
| 976 case 14: |
| 977 if (PDF_CharType[byte] == 'W') { |
| 978 status = 0; |
| 979 } else if (byte == '%' || byte == '(' || byte == '<' || |
| 980 byte == '\\') { |
| 981 status = 0; |
| 982 --i; |
| 983 } else if (inside_index == 6) { |
| 984 status = 0; |
| 985 --i; |
| 986 } else if (byte == "endobj"[inside_index]) { |
| 987 inside_index++; |
| 988 } |
| 989 break; |
| 990 } |
| 991 if (bOverFlow) { |
| 992 size = 0; |
| 993 break; |
| 994 } |
| 995 } |
| 996 pos += size; |
| 997 } |
| 998 if (last_xref != -1 && last_xref > last_obj) { |
| 999 last_trailer = last_xref; |
| 1000 } else if (last_trailer == -1 || last_xref < last_obj) { |
| 1001 last_trailer = m_Syntax.m_FileLen; |
| 1002 } |
| 1003 FX_FILESIZE offset = last_trailer - m_Syntax.m_HeaderOffset; |
| 1004 void* pResult = |
| 1005 FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), |
| 1006 sizeof(FX_FILESIZE), _CompareFileSize); |
| 1007 if (pResult == NULL) { |
| 1008 m_SortedOffset.Add(offset); |
| 1009 } |
| 1010 FX_Free(buffer); |
| 1011 return TRUE; |
| 1012 } |
| 1013 static FX_DWORD _GetVarInt(const uint8_t* p, int32_t n) { |
| 1014 FX_DWORD result = 0; |
| 1015 for (int32_t i = 0; i < n; i++) { |
| 1016 result = result * 256 + p[i]; |
| 1017 } |
| 1018 return result; |
| 1019 } |
| 1020 FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE pos, |
| 1021 FX_FILESIZE& prev, |
| 1022 FX_BOOL bMainXRef) { |
| 1023 CPDF_Stream* pStream = |
| 1024 (CPDF_Stream*)ParseIndirectObjectAt(m_pDocument, pos, 0, NULL); |
| 1025 if (!pStream) { |
| 1026 return FALSE; |
| 1027 } |
| 1028 if (m_pDocument) { |
| 1029 CPDF_Dictionary* pDict = m_pDocument->GetRoot(); |
| 1030 if (!pDict || pDict->GetObjNum() != pStream->m_ObjNum) { |
| 1031 m_pDocument->InsertIndirectObject(pStream->m_ObjNum, pStream); |
| 1032 } else { |
| 1033 if (pStream->GetType() == PDFOBJ_STREAM) { |
| 1034 pStream->Release(); |
| 1035 } |
| 1036 return FALSE; |
| 1037 } |
| 1038 } |
| 1039 if (pStream->GetType() != PDFOBJ_STREAM) { |
| 1040 return FALSE; |
| 1041 } |
| 1042 prev = pStream->GetDict()->GetInteger(FX_BSTRC("Prev")); |
| 1043 int32_t size = pStream->GetDict()->GetInteger(FX_BSTRC("Size")); |
| 1044 if (size < 0) { |
| 1045 pStream->Release(); |
| 1046 return FALSE; |
| 1047 } |
| 1048 if (bMainXRef) { |
| 1049 m_pTrailer = (CPDF_Dictionary*)pStream->GetDict()->Clone(); |
| 1050 m_CrossRef.SetSize(size); |
| 1051 if (m_V5Type.SetSize(size)) { |
| 1052 FXSYS_memset(m_V5Type.GetData(), 0, size); |
| 1053 } |
| 1054 } else { |
| 1055 m_Trailers.Add((CPDF_Dictionary*)pStream->GetDict()->Clone()); |
| 1056 } |
| 1057 std::vector<std::pair<int32_t, int32_t> > arrIndex; |
| 1058 CPDF_Array* pArray = pStream->GetDict()->GetArray(FX_BSTRC("Index")); |
| 1059 if (pArray) { |
| 1060 FX_DWORD nPairSize = pArray->GetCount() / 2; |
| 1061 for (FX_DWORD i = 0; i < nPairSize; i++) { |
| 1062 CPDF_Object* pStartNumObj = pArray->GetElement(i * 2); |
| 1063 CPDF_Object* pCountObj = pArray->GetElement(i * 2 + 1); |
| 1064 if (pStartNumObj && pStartNumObj->GetType() == PDFOBJ_NUMBER && |
| 1065 pCountObj && pCountObj->GetType() == PDFOBJ_NUMBER) { |
| 1066 int nStartNum = pStartNumObj->GetInteger(); |
| 1067 int nCount = pCountObj->GetInteger(); |
| 1068 if (nStartNum >= 0 && nCount > 0) { |
| 1069 arrIndex.push_back(std::make_pair(nStartNum, nCount)); |
| 1070 } |
| 1071 } |
| 1072 } |
| 1073 } |
| 1074 if (arrIndex.size() == 0) { |
| 1075 arrIndex.push_back(std::make_pair(0, size)); |
| 1076 } |
| 1077 pArray = pStream->GetDict()->GetArray(FX_BSTRC("W")); |
| 1078 if (pArray == NULL) { |
| 1079 pStream->Release(); |
| 1080 return FALSE; |
| 1081 } |
| 1082 CFX_DWordArray WidthArray; |
| 1083 FX_SAFE_DWORD dwAccWidth = 0; |
| 1084 for (FX_DWORD i = 0; i < pArray->GetCount(); i++) { |
| 1085 WidthArray.Add(pArray->GetInteger(i)); |
| 1086 dwAccWidth += WidthArray[i]; |
| 1087 } |
| 1088 if (!dwAccWidth.IsValid() || WidthArray.GetSize() < 3) { |
| 1089 pStream->Release(); |
| 1090 return FALSE; |
| 1091 } |
| 1092 FX_DWORD totalWidth = dwAccWidth.ValueOrDie(); |
| 1093 CPDF_StreamAcc acc; |
| 1094 acc.LoadAllData(pStream); |
| 1095 const uint8_t* pData = acc.GetData(); |
| 1096 FX_DWORD dwTotalSize = acc.GetSize(); |
| 1097 FX_DWORD segindex = 0; |
| 1098 for (FX_DWORD i = 0; i < arrIndex.size(); i++) { |
| 1099 int32_t startnum = arrIndex[i].first; |
| 1100 if (startnum < 0) { |
| 1101 continue; |
| 1102 } |
| 1103 m_dwXrefStartObjNum = |
| 1104 pdfium::base::checked_cast<FX_DWORD, int32_t>(startnum); |
| 1105 FX_DWORD count = |
| 1106 pdfium::base::checked_cast<FX_DWORD, int32_t>(arrIndex[i].second); |
| 1107 FX_SAFE_DWORD dwCaculatedSize = segindex; |
| 1108 dwCaculatedSize += count; |
| 1109 dwCaculatedSize *= totalWidth; |
| 1110 if (!dwCaculatedSize.IsValid() || |
| 1111 dwCaculatedSize.ValueOrDie() > dwTotalSize) { |
| 1112 continue; |
| 1113 } |
| 1114 const uint8_t* segstart = pData + segindex * totalWidth; |
| 1115 FX_SAFE_DWORD dwMaxObjNum = startnum; |
| 1116 dwMaxObjNum += count; |
| 1117 FX_DWORD dwV5Size = |
| 1118 pdfium::base::checked_cast<FX_DWORD, int32_t>(m_V5Type.GetSize()); |
| 1119 if (!dwMaxObjNum.IsValid() || dwMaxObjNum.ValueOrDie() > dwV5Size) { |
| 1120 continue; |
| 1121 } |
| 1122 for (FX_DWORD j = 0; j < count; j++) { |
| 1123 int32_t type = 1; |
| 1124 const uint8_t* entrystart = segstart + j * totalWidth; |
| 1125 if (WidthArray[0]) { |
| 1126 type = _GetVarInt(entrystart, WidthArray[0]); |
| 1127 } |
| 1128 if (m_V5Type[startnum + j] == 255) { |
| 1129 FX_FILESIZE offset = |
| 1130 _GetVarInt(entrystart + WidthArray[0], WidthArray[1]); |
| 1131 m_CrossRef[startnum + j] = offset; |
| 1132 void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), |
| 1133 m_SortedOffset.GetSize(), |
| 1134 sizeof(FX_FILESIZE), _CompareFileSize); |
| 183 if (pResult == NULL) { | 1135 if (pResult == NULL) { |
| 184 m_SortedOffset.Add(startxref_offset); | 1136 m_SortedOffset.Add(offset); |
| 185 } | 1137 } |
| 186 m_Syntax.GetKeyword(); | 1138 continue; |
| 187 FX_BOOL bNumber; | 1139 } |
| 188 CFX_ByteString xrefpos_str = m_Syntax.GetNextWord(bNumber); | 1140 if (m_V5Type[startnum + j]) { |
| 189 if (!bNumber) { | 1141 continue; |
| 190 return PDFPARSE_ERROR_FORMAT; | 1142 } |
| 191 } | 1143 m_V5Type[startnum + j] = type; |
| 192 m_LastXRefOffset = (FX_FILESIZE)FXSYS_atoi64(xrefpos_str); | 1144 if (type == 0) { |
| 193 if (!LoadAllCrossRefV4(m_LastXRefOffset) && !LoadAllCrossRefV5(m_LastXRe
fOffset)) { | 1145 m_CrossRef[startnum + j] = 0; |
| 194 if (!RebuildCrossRef()) { | 1146 } else { |
| 195 return PDFPARSE_ERROR_FORMAT; | 1147 FX_FILESIZE offset = |
| 196 } | 1148 _GetVarInt(entrystart + WidthArray[0], WidthArray[1]); |
| 197 bXRefRebuilt = TRUE; | 1149 m_CrossRef[startnum + j] = offset; |
| 198 m_LastXRefOffset = 0; | 1150 if (type == 1) { |
| 199 } | 1151 void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), |
| 200 } else { | 1152 m_SortedOffset.GetSize(), |
| 201 if (!RebuildCrossRef()) { | 1153 sizeof(FX_FILESIZE), _CompareFileSize); |
| 202 return PDFPARSE_ERROR_FORMAT; | 1154 if (pResult == NULL) { |
| 203 } | 1155 m_SortedOffset.Add(offset); |
| 204 bXRefRebuilt = TRUE; | 1156 } |
| 205 } | 1157 } else { |
| 206 FX_DWORD dwRet = SetEncryptHandler(); | 1158 if (offset < 0 || offset >= m_V5Type.GetSize()) { |
| 207 if (dwRet != PDFPARSE_ERROR_SUCCESS) { | 1159 pStream->Release(); |
| 208 return dwRet; | 1160 return FALSE; |
| 209 } | 1161 } |
| 210 m_pDocument->LoadDoc(); | 1162 m_V5Type[offset] = 255; |
| 211 if (m_pDocument->GetRoot() == NULL || m_pDocument->GetPageCount() == 0) { | 1163 } |
| 212 if (bXRefRebuilt) { | 1164 } |
| 213 return PDFPARSE_ERROR_FORMAT; | 1165 } |
| 214 } | 1166 segindex += count; |
| 215 ReleaseEncryptHandler(); | 1167 } |
| 216 if (!RebuildCrossRef()) { | 1168 pStream->Release(); |
| 217 return PDFPARSE_ERROR_FORMAT; | 1169 return TRUE; |
| 218 } | 1170 } |
| 219 dwRet = SetEncryptHandler(); | 1171 CPDF_Array* CPDF_Parser::GetIDArray() { |
| 220 if (dwRet != PDFPARSE_ERROR_SUCCESS) { | 1172 CPDF_Object* pID = m_pTrailer ? m_pTrailer->GetElement(FX_BSTRC("ID")) : NULL; |
| 221 return dwRet; | 1173 if (pID == NULL) { |
| 222 } | 1174 return NULL; |
| 223 m_pDocument->LoadDoc(); | 1175 } |
| 224 if (m_pDocument->GetRoot() == NULL) { | 1176 if (pID->GetType() == PDFOBJ_REFERENCE) { |
| 225 return PDFPARSE_ERROR_FORMAT; | 1177 pID = ParseIndirectObject(NULL, ((CPDF_Reference*)pID)->GetRefObjNum()); |
| 226 } | 1178 m_pTrailer->SetAt(FX_BSTRC("ID"), pID); |
| 227 } | 1179 } |
| 228 FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FI
LESIZE), _CompareFileSize); | 1180 if (pID == NULL || pID->GetType() != PDFOBJ_ARRAY) { |
| 229 FX_DWORD RootObjNum = GetRootObjNum(); | 1181 return NULL; |
| 230 if (RootObjNum == 0) { | 1182 } |
| 231 ReleaseEncryptHandler(); | 1183 return (CPDF_Array*)pID; |
| 232 RebuildCrossRef(); | 1184 } |
| 233 RootObjNum = GetRootObjNum(); | 1185 FX_DWORD CPDF_Parser::GetRootObjNum() { |
| 234 if (RootObjNum == 0) { | 1186 CPDF_Object* pRef = |
| 235 return PDFPARSE_ERROR_FORMAT; | 1187 m_pTrailer ? m_pTrailer->GetElement(FX_BSTRC("Root")) : NULL; |
| 236 } | 1188 if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) { |
| 237 dwRet = SetEncryptHandler(); | |
| 238 if (dwRet != PDFPARSE_ERROR_SUCCESS) { | |
| 239 return dwRet; | |
| 240 } | |
| 241 } | |
| 242 if (m_pSecurityHandler && !m_pSecurityHandler->IsMetadataEncrypted()) { | |
| 243 CPDF_Reference* pMetadata = (CPDF_Reference*)m_pDocument->GetRoot()->Get
Element(FX_BSTRC("Metadata")); | |
| 244 if (pMetadata && pMetadata->GetType() == PDFOBJ_REFERENCE) { | |
| 245 m_Syntax.m_MetadataObjnum = pMetadata->GetRefObjNum(); | |
| 246 } | |
| 247 } | |
| 248 return PDFPARSE_ERROR_SUCCESS; | |
| 249 } | |
| 250 FX_DWORD CPDF_Parser::SetEncryptHandler() | |
| 251 { | |
| 252 ReleaseEncryptHandler(); | |
| 253 SetEncryptDictionary(NULL); | |
| 254 if (m_pTrailer == NULL) { | |
| 255 return PDFPARSE_ERROR_FORMAT; | |
| 256 } | |
| 257 CPDF_Object* pEncryptObj = m_pTrailer->GetElement(FX_BSTRC("Encrypt")); | |
| 258 if (pEncryptObj) { | |
| 259 if (pEncryptObj->GetType() == PDFOBJ_DICTIONARY) { | |
| 260 SetEncryptDictionary((CPDF_Dictionary*)pEncryptObj); | |
| 261 } else if (pEncryptObj->GetType() == PDFOBJ_REFERENCE) { | |
| 262 pEncryptObj = m_pDocument->GetIndirectObject(((CPDF_Reference*)pEncr
yptObj)->GetRefObjNum()); | |
| 263 if (pEncryptObj) { | |
| 264 SetEncryptDictionary(pEncryptObj->GetDict()); | |
| 265 } | |
| 266 } | |
| 267 } | |
| 268 if (m_bForceUseSecurityHandler) { | |
| 269 FX_DWORD err = PDFPARSE_ERROR_HANDLER; | |
| 270 if (m_pSecurityHandler == NULL) { | |
| 271 return PDFPARSE_ERROR_HANDLER; | |
| 272 } | |
| 273 if (!m_pSecurityHandler->OnInit(this, m_pEncryptDict)) { | |
| 274 return err; | |
| 275 } | |
| 276 CPDF_CryptoHandler* pCryptoHandler = m_pSecurityHandler->CreateCryptoHan
dler(); | |
| 277 if (!pCryptoHandler->Init(m_pEncryptDict, m_pSecurityHandler)) { | |
| 278 delete pCryptoHandler; | |
| 279 pCryptoHandler = NULL; | |
| 280 return PDFPARSE_ERROR_HANDLER; | |
| 281 } | |
| 282 m_Syntax.SetEncrypt(pCryptoHandler); | |
| 283 } else if (m_pEncryptDict) { | |
| 284 CFX_ByteString filter = m_pEncryptDict->GetString(FX_BSTRC("Filter")); | |
| 285 CPDF_SecurityHandler* pSecurityHandler = NULL; | |
| 286 FX_DWORD err = PDFPARSE_ERROR_HANDLER; | |
| 287 if (filter == FX_BSTRC("Standard")) { | |
| 288 pSecurityHandler = FPDF_CreateStandardSecurityHandler(); | |
| 289 err = PDFPARSE_ERROR_PASSWORD; | |
| 290 } | |
| 291 if (pSecurityHandler == NULL) { | |
| 292 return PDFPARSE_ERROR_HANDLER; | |
| 293 } | |
| 294 if (!pSecurityHandler->OnInit(this, m_pEncryptDict)) { | |
| 295 delete pSecurityHandler; | |
| 296 pSecurityHandler = NULL; | |
| 297 return err; | |
| 298 } | |
| 299 m_pSecurityHandler = pSecurityHandler; | |
| 300 CPDF_CryptoHandler* pCryptoHandler = pSecurityHandler->CreateCryptoHandl
er(); | |
| 301 if (!pCryptoHandler->Init(m_pEncryptDict, m_pSecurityHandler)) { | |
| 302 delete pCryptoHandler; | |
| 303 pCryptoHandler = NULL; | |
| 304 return PDFPARSE_ERROR_HANDLER; | |
| 305 } | |
| 306 m_Syntax.SetEncrypt(pCryptoHandler); | |
| 307 } | |
| 308 return PDFPARSE_ERROR_SUCCESS; | |
| 309 } | |
| 310 void CPDF_Parser::ReleaseEncryptHandler() | |
| 311 { | |
| 312 delete m_Syntax.m_pCryptoHandler; | |
| 313 m_Syntax.m_pCryptoHandler = NULL; | |
| 314 if (!m_bForceUseSecurityHandler) { | |
| 315 delete m_pSecurityHandler; | |
| 316 m_pSecurityHandler = NULL; | |
| 317 } | |
| 318 } | |
| 319 FX_FILESIZE CPDF_Parser::GetObjectOffset(FX_DWORD objnum) | |
| 320 { | |
| 321 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) { | |
| 322 return 0; | |
| 323 } | |
| 324 if (m_V5Type[objnum] == 1) { | |
| 325 return m_CrossRef[objnum]; | |
| 326 } | |
| 327 if (m_V5Type[objnum] == 2) { | |
| 328 return m_CrossRef[(int32_t)m_CrossRef[objnum]]; | |
| 329 } | |
| 330 return 0; | 1189 return 0; |
| 331 } | 1190 } |
| 332 static int32_t GetDirectInteger(CPDF_Dictionary* pDict, const CFX_ByteStringC& k
ey) | 1191 return ((CPDF_Reference*)pRef)->GetRefObjNum(); |
| 333 { | 1192 } |
| 334 CPDF_Object* pObj = pDict->GetElement(key); | 1193 FX_DWORD CPDF_Parser::GetInfoObjNum() { |
| 335 if (pObj == NULL) { | 1194 CPDF_Object* pRef = |
| 336 return 0; | 1195 m_pTrailer ? m_pTrailer->GetElement(FX_BSTRC("Info")) : NULL; |
| 337 } | 1196 if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) { |
| 338 if (pObj->GetType() == PDFOBJ_NUMBER) { | |
| 339 return ((CPDF_Number*)pObj)->GetInteger(); | |
| 340 } | |
| 341 return 0; | 1197 return 0; |
| 342 } | 1198 } |
| 343 static FX_BOOL CheckDirectType(CPDF_Dictionary* pDict, const CFX_ByteStringC& ke
y, int32_t iType) | 1199 return ((CPDF_Reference*)pRef)->GetRefObjNum(); |
| 344 { | 1200 } |
| 345 CPDF_Object* pObj = pDict->GetElement(key); | 1201 FX_BOOL CPDF_Parser::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm) { |
| 346 if (!pObj) { | 1202 bForm = FALSE; |
| 347 return TRUE; | 1203 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) { |
| 348 } | |
| 349 return pObj->GetType() == iType; | |
| 350 } | |
| 351 FX_BOOL CPDF_Parser::LoadAllCrossRefV4(FX_FILESIZE xrefpos) | |
| 352 { | |
| 353 if (!LoadCrossRefV4(xrefpos, 0, TRUE, FALSE)) { | |
| 354 return FALSE; | |
| 355 } | |
| 356 m_pTrailer = LoadTrailerV4(); | |
| 357 if (m_pTrailer == NULL) { | |
| 358 return FALSE; | |
| 359 } | |
| 360 int32_t xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size")); | |
| 361 if (xrefsize <= 0 || xrefsize > (1 << 20)) { | |
| 362 return FALSE; | |
| 363 } | |
| 364 m_CrossRef.SetSize(xrefsize); | |
| 365 m_V5Type.SetSize(xrefsize); | |
| 366 CFX_FileSizeArray CrossRefList, XRefStreamList; | |
| 367 CrossRefList.Add(xrefpos); | |
| 368 XRefStreamList.Add(GetDirectInteger(m_pTrailer, FX_BSTRC("XRefStm"))); | |
| 369 if (!CheckDirectType(m_pTrailer, FX_BSTRC("Prev"), PDFOBJ_NUMBER)) { | |
| 370 return FALSE; | |
| 371 } | |
| 372 FX_FILESIZE newxrefpos = GetDirectInteger(m_pTrailer, FX_BSTRC("Prev")); | |
| 373 if (newxrefpos == xrefpos) { | |
| 374 return FALSE; | |
| 375 } | |
| 376 xrefpos = newxrefpos; | |
| 377 while (xrefpos) { | |
| 378 CrossRefList.InsertAt(0, xrefpos); | |
| 379 LoadCrossRefV4(xrefpos, 0, TRUE, FALSE); | |
| 380 CPDF_Dictionary* pDict = LoadTrailerV4(); | |
| 381 if (pDict == NULL) { | |
| 382 return FALSE; | |
| 383 } | |
| 384 if (!CheckDirectType(pDict, FX_BSTRC("Prev"), PDFOBJ_NUMBER)) { | |
| 385 pDict->Release(); | |
| 386 return FALSE; | |
| 387 } | |
| 388 newxrefpos = GetDirectInteger(pDict, FX_BSTRC("Prev")); | |
| 389 if (newxrefpos == xrefpos) { | |
| 390 pDict->Release(); | |
| 391 return FALSE; | |
| 392 } | |
| 393 xrefpos = newxrefpos; | |
| 394 XRefStreamList.InsertAt(0, pDict->GetInteger(FX_BSTRC("XRefStm"))); | |
| 395 m_Trailers.Add(pDict); | |
| 396 } | |
| 397 for (int32_t i = 0; i < CrossRefList.GetSize(); i ++) | |
| 398 if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE, i == 0))
{ | |
| 399 return FALSE; | |
| 400 } | |
| 401 return TRUE; | 1204 return TRUE; |
| 402 } | 1205 } |
| 403 FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV4(FX_FILESIZE xrefpos, FX_DWORD d
wObjCount) | 1206 if (m_V5Type[objnum] == 0) { |
| 404 { | |
| 405 if (!LoadLinearizedCrossRefV4(xrefpos, dwObjCount)) { | |
| 406 return FALSE; | |
| 407 } | |
| 408 m_pTrailer = LoadTrailerV4(); | |
| 409 if (m_pTrailer == NULL) { | |
| 410 return FALSE; | |
| 411 } | |
| 412 int32_t xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size")); | |
| 413 if (xrefsize == 0) { | |
| 414 return FALSE; | |
| 415 } | |
| 416 CFX_FileSizeArray CrossRefList, XRefStreamList; | |
| 417 CrossRefList.Add(xrefpos); | |
| 418 XRefStreamList.Add(GetDirectInteger(m_pTrailer, FX_BSTRC("XRefStm"))); | |
| 419 xrefpos = GetDirectInteger(m_pTrailer, FX_BSTRC("Prev")); | |
| 420 while (xrefpos) { | |
| 421 CrossRefList.InsertAt(0, xrefpos); | |
| 422 LoadCrossRefV4(xrefpos, 0, TRUE, FALSE); | |
| 423 CPDF_Dictionary* pDict = LoadTrailerV4(); | |
| 424 if (pDict == NULL) { | |
| 425 return FALSE; | |
| 426 } | |
| 427 xrefpos = GetDirectInteger(pDict, FX_BSTRC("Prev")); | |
| 428 XRefStreamList.InsertAt(0, pDict->GetInteger(FX_BSTRC("XRefStm"))); | |
| 429 m_Trailers.Add(pDict); | |
| 430 } | |
| 431 for (int32_t i = 1; i < CrossRefList.GetSize(); i ++) | |
| 432 if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE, i == 0))
{ | |
| 433 return FALSE; | |
| 434 } | |
| 435 return TRUE; | 1207 return TRUE; |
| 436 } | 1208 } |
| 437 FX_BOOL CPDF_Parser::LoadLinearizedCrossRefV4(FX_FILESIZE pos, FX_DWORD dwObjCou
nt) | 1209 if (m_V5Type[objnum] == 2) { |
| 438 { | 1210 return TRUE; |
| 439 FX_FILESIZE dwStartPos = pos - m_Syntax.m_HeaderOffset; | 1211 } |
| 440 m_Syntax.RestorePos(dwStartPos); | 1212 FX_FILESIZE pos = m_CrossRef[objnum]; |
| 441 void* pResult = FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset
.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); | 1213 void* pResult = |
| 1214 FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), |
| 1215 sizeof(FX_FILESIZE), _CompareFileSize); |
| 1216 if (pResult == NULL) { |
| 1217 return TRUE; |
| 1218 } |
| 1219 if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)m_SortedOffset.GetData() == |
| 1220 m_SortedOffset.GetSize() - 1) { |
| 1221 return FALSE; |
| 1222 } |
| 1223 FX_FILESIZE size = ((FX_FILESIZE*)pResult)[1] - pos; |
| 1224 FX_FILESIZE SavedPos = m_Syntax.SavePos(); |
| 1225 m_Syntax.RestorePos(pos); |
| 1226 bForm = m_Syntax.SearchMultiWord(FX_BSTRC("/Form\0stream"), TRUE, size) == 0; |
| 1227 m_Syntax.RestorePos(SavedPos); |
| 1228 return TRUE; |
| 1229 } |
| 1230 CPDF_Object* CPDF_Parser::ParseIndirectObject(CPDF_IndirectObjects* pObjList, |
| 1231 FX_DWORD objnum, |
| 1232 PARSE_CONTEXT* pContext) { |
| 1233 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) { |
| 1234 return NULL; |
| 1235 } |
| 1236 if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) { |
| 1237 FX_FILESIZE pos = m_CrossRef[objnum]; |
| 1238 if (pos <= 0) { |
| 1239 return NULL; |
| 1240 } |
| 1241 return ParseIndirectObjectAt(pObjList, pos, objnum, pContext); |
| 1242 } |
| 1243 if (m_V5Type[objnum] == 2) { |
| 1244 CPDF_StreamAcc* pObjStream = GetObjectStream((FX_DWORD)m_CrossRef[objnum]); |
| 1245 if (pObjStream == NULL) { |
| 1246 return NULL; |
| 1247 } |
| 1248 int32_t n = pObjStream->GetDict()->GetInteger(FX_BSTRC("N")); |
| 1249 int32_t offset = pObjStream->GetDict()->GetInteger(FX_BSTRC("First")); |
| 1250 CPDF_SyntaxParser syntax; |
| 1251 CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream( |
| 1252 (uint8_t*)pObjStream->GetData(), (size_t)pObjStream->GetSize(), FALSE)); |
| 1253 syntax.InitParser(file.Get(), 0); |
| 1254 CPDF_Object* pRet = NULL; |
| 1255 while (n) { |
| 1256 FX_DWORD thisnum = syntax.GetDirectNum(); |
| 1257 FX_DWORD thisoff = syntax.GetDirectNum(); |
| 1258 if (thisnum == objnum) { |
| 1259 syntax.RestorePos(offset + thisoff); |
| 1260 pRet = syntax.GetObject(pObjList, 0, 0, pContext); |
| 1261 break; |
| 1262 } |
| 1263 n--; |
| 1264 } |
| 1265 return pRet; |
| 1266 } |
| 1267 return NULL; |
| 1268 } |
| 1269 CPDF_StreamAcc* CPDF_Parser::GetObjectStream(FX_DWORD objnum) { |
| 1270 CPDF_StreamAcc* pStreamAcc = NULL; |
| 1271 if (m_ObjectStreamMap.Lookup((void*)(uintptr_t)objnum, (void*&)pStreamAcc)) { |
| 1272 return pStreamAcc; |
| 1273 } |
| 1274 const CPDF_Stream* pStream = |
| 1275 m_pDocument ? (CPDF_Stream*)m_pDocument->GetIndirectObject(objnum) : NULL; |
| 1276 if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM) { |
| 1277 return NULL; |
| 1278 } |
| 1279 pStreamAcc = new CPDF_StreamAcc; |
| 1280 pStreamAcc->LoadAllData(pStream); |
| 1281 m_ObjectStreamMap.SetAt((void*)(uintptr_t)objnum, pStreamAcc); |
| 1282 return pStreamAcc; |
| 1283 } |
| 1284 FX_FILESIZE CPDF_Parser::GetObjectSize(FX_DWORD objnum) { |
| 1285 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) { |
| 1286 return 0; |
| 1287 } |
| 1288 if (m_V5Type[objnum] == 2) { |
| 1289 objnum = (FX_DWORD)m_CrossRef[objnum]; |
| 1290 } |
| 1291 if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) { |
| 1292 FX_FILESIZE offset = m_CrossRef[objnum]; |
| 1293 if (offset == 0) { |
| 1294 return 0; |
| 1295 } |
| 1296 void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), |
| 1297 m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), |
| 1298 _CompareFileSize); |
| 442 if (pResult == NULL) { | 1299 if (pResult == NULL) { |
| 443 m_SortedOffset.Add(pos); | 1300 return 0; |
| 444 } | 1301 } |
| 445 FX_DWORD start_objnum = 0; | 1302 if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)m_SortedOffset.GetData() == |
| 446 FX_DWORD count = dwObjCount; | 1303 m_SortedOffset.GetSize() - 1) { |
| 447 FX_FILESIZE SavedPos = m_Syntax.SavePos(); | 1304 return 0; |
| 448 int32_t recordsize = 20; | 1305 } |
| 449 char* pBuf = FX_Alloc(char, 1024 * recordsize + 1); | 1306 return ((FX_FILESIZE*)pResult)[1] - offset; |
| 450 pBuf[1024 * recordsize] = '\0'; | 1307 } |
| 451 int32_t nBlocks = count / 1024 + 1; | 1308 return 0; |
| 452 for (int32_t block = 0; block < nBlocks; block ++) { | 1309 } |
| 453 int32_t block_size = block == nBlocks - 1 ? count % 1024 : 1024; | 1310 void CPDF_Parser::GetIndirectBinary(FX_DWORD objnum, |
| 454 FX_DWORD dwReadSize = block_size * recordsize; | 1311 uint8_t*& pBuffer, |
| 455 if ((FX_FILESIZE)(dwStartPos + dwReadSize) > m_Syntax.m_FileLen) { | 1312 FX_DWORD& size) { |
| 456 FX_Free(pBuf); | 1313 pBuffer = NULL; |
| 457 return FALSE; | 1314 size = 0; |
| 458 } | 1315 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) { |
| 459 if (!m_Syntax.ReadBlock((uint8_t*)pBuf, dwReadSize)) { | 1316 return; |
| 460 FX_Free(pBuf); | 1317 } |
| 461 return FALSE; | 1318 if (m_V5Type[objnum] == 2) { |
| 462 } | 1319 CPDF_StreamAcc* pObjStream = GetObjectStream((FX_DWORD)m_CrossRef[objnum]); |
| 463 for (int32_t i = 0; i < block_size; i ++) { | 1320 if (pObjStream == NULL) { |
| 464 FX_DWORD objnum = start_objnum + block * 1024 + i; | 1321 return; |
| 465 char* pEntry = pBuf + i * recordsize; | 1322 } |
| 466 if (pEntry[17] == 'f') { | 1323 int32_t n = pObjStream->GetDict()->GetInteger(FX_BSTRC("N")); |
| 467 m_CrossRef.SetAtGrow(objnum, 0); | 1324 int32_t offset = pObjStream->GetDict()->GetInteger(FX_BSTRC("First")); |
| 468 m_V5Type.SetAtGrow(objnum, 0); | 1325 CPDF_SyntaxParser syntax; |
| 469 } else { | 1326 const uint8_t* pData = pObjStream->GetData(); |
| 470 int32_t offset = FXSYS_atoi(pEntry); | 1327 FX_DWORD totalsize = pObjStream->GetSize(); |
| 471 if (offset == 0) { | 1328 CFX_SmartPointer<IFX_FileStream> file( |
| 472 for (int32_t c = 0; c < 10; c ++) { | 1329 FX_CreateMemoryStream((uint8_t*)pData, (size_t)totalsize, FALSE)); |
| 473 if (pEntry[c] < '0' || pEntry[c] > '9') { | 1330 syntax.InitParser(file.Get(), 0); |
| 474 FX_Free(pBuf); | 1331 while (n) { |
| 475 return FALSE; | 1332 FX_DWORD thisnum = syntax.GetDirectNum(); |
| 476 } | 1333 FX_DWORD thisoff = syntax.GetDirectNum(); |
| 477 } | 1334 if (thisnum == objnum) { |
| 478 } | 1335 if (n == 1) { |
| 479 m_CrossRef.SetAtGrow(objnum, offset); | 1336 size = totalsize - (thisoff + offset); |
| 480 int32_t version = FXSYS_atoi(pEntry + 11); | |
| 481 if (version >= 1) { | |
| 482 m_bVersionUpdated = TRUE; | |
| 483 } | |
| 484 m_ObjVersion.SetAtGrow(objnum, version); | |
| 485 if (m_CrossRef[objnum] < m_Syntax.m_FileLen) { | |
| 486 void* pResult = FXSYS_bsearch(&m_CrossRef[objnum], m_SortedO
ffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize
); | |
| 487 if (pResult == NULL) { | |
| 488 m_SortedOffset.Add(m_CrossRef[objnum]); | |
| 489 } | |
| 490 } | |
| 491 m_V5Type.SetAtGrow(objnum, 1); | |
| 492 } | |
| 493 } | |
| 494 } | |
| 495 FX_Free(pBuf); | |
| 496 m_Syntax.RestorePos(SavedPos + count * recordsize); | |
| 497 return TRUE; | |
| 498 } | |
| 499 FX_BOOL CPDF_Parser::LoadCrossRefV4(FX_FILESIZE pos, FX_FILESIZE streampos, FX_B
OOL bSkip, FX_BOOL bFirst) | |
| 500 { | |
| 501 m_Syntax.RestorePos(pos); | |
| 502 if (m_Syntax.GetKeyword() != FX_BSTRC("xref")) { | |
| 503 return FALSE; | |
| 504 } | |
| 505 void* pResult = FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset
.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); | |
| 506 if (pResult == NULL) { | |
| 507 m_SortedOffset.Add(pos); | |
| 508 } | |
| 509 if (streampos) { | |
| 510 void* pResult = FXSYS_bsearch(&streampos, m_SortedOffset.GetData(), m_So
rtedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); | |
| 511 if (pResult == NULL) { | |
| 512 m_SortedOffset.Add(streampos); | |
| 513 } | |
| 514 } | |
| 515 while (1) { | |
| 516 FX_FILESIZE SavedPos = m_Syntax.SavePos(); | |
| 517 FX_BOOL bIsNumber; | |
| 518 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); | |
| 519 if (word.IsEmpty()) { | |
| 520 return FALSE; | |
| 521 } | |
| 522 if (!bIsNumber) { | |
| 523 m_Syntax.RestorePos(SavedPos); | |
| 524 break; | |
| 525 } | |
| 526 FX_DWORD start_objnum = FXSYS_atoi(word); | |
| 527 if (start_objnum >= (1 << 20)) { | |
| 528 return FALSE; | |
| 529 } | |
| 530 FX_DWORD count = m_Syntax.GetDirectNum(); | |
| 531 m_Syntax.ToNextWord(); | |
| 532 SavedPos = m_Syntax.SavePos(); | |
| 533 FX_BOOL bFirstItem = FALSE; | |
| 534 int32_t recordsize = 20; | |
| 535 if (bFirst) { | |
| 536 bFirstItem = TRUE; | |
| 537 } | |
| 538 m_dwXrefStartObjNum = start_objnum; | |
| 539 if (!bSkip) { | |
| 540 char* pBuf = FX_Alloc(char, 1024 * recordsize + 1); | |
| 541 pBuf[1024 * recordsize] = '\0'; | |
| 542 int32_t nBlocks = count / 1024 + 1; | |
| 543 FX_BOOL bFirstBlock = TRUE; | |
| 544 for (int32_t block = 0; block < nBlocks; block ++) { | |
| 545 int32_t block_size = block == nBlocks - 1 ? count % 1024 : 1024; | |
| 546 m_Syntax.ReadBlock((uint8_t*)pBuf, block_size * recordsize); | |
| 547 for (int32_t i = 0; i < block_size; i ++) { | |
| 548 FX_DWORD objnum = start_objnum + block * 1024 + i; | |
| 549 char* pEntry = pBuf + i * recordsize; | |
| 550 if (pEntry[17] == 'f') { | |
| 551 if (bFirstItem) { | |
| 552 objnum = 0; | |
| 553 bFirstItem = FALSE; | |
| 554 } | |
| 555 if (bFirstBlock) { | |
| 556 FX_FILESIZE offset = (FX_FILESIZE)FXSYS_atoi64(pEntr
y); | |
| 557 int32_t version = FXSYS_atoi(pEntry + 11); | |
| 558 if (offset == 0 && version == 65535 && start_objnum
!= 0) { | |
| 559 start_objnum--; | |
| 560 objnum = 0; | |
| 561 } | |
| 562 } | |
| 563 m_CrossRef.SetAtGrow(objnum, 0); | |
| 564 m_V5Type.SetAtGrow(objnum, 0); | |
| 565 } else { | |
| 566 FX_FILESIZE offset = (FX_FILESIZE)FXSYS_atoi64(pEntry); | |
| 567 if (offset == 0) { | |
| 568 for (int32_t c = 0; c < 10; c ++) { | |
| 569 if (pEntry[c] < '0' || pEntry[c] > '9') { | |
| 570 FX_Free(pBuf); | |
| 571 return FALSE; | |
| 572 } | |
| 573 } | |
| 574 } | |
| 575 m_CrossRef.SetAtGrow(objnum, offset); | |
| 576 int32_t version = FXSYS_atoi(pEntry + 11); | |
| 577 if (version >= 1) { | |
| 578 m_bVersionUpdated = TRUE; | |
| 579 } | |
| 580 m_ObjVersion.SetAtGrow(objnum, version); | |
| 581 if (m_CrossRef[objnum] < m_Syntax.m_FileLen) { | |
| 582 void* pResult = FXSYS_bsearch(&m_CrossRef[objnum], m
_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _Compare
FileSize); | |
| 583 if (pResult == NULL) { | |
| 584 m_SortedOffset.Add(m_CrossRef[objnum]); | |
| 585 } | |
| 586 } | |
| 587 m_V5Type.SetAtGrow(objnum, 1); | |
| 588 } | |
| 589 if (bFirstBlock) { | |
| 590 bFirstBlock = FALSE; | |
| 591 } | |
| 592 } | |
| 593 } | |
| 594 FX_Free(pBuf); | |
| 595 } | |
| 596 m_Syntax.RestorePos(SavedPos + count * recordsize); | |
| 597 } | |
| 598 if (streampos) | |
| 599 if (!LoadCrossRefV5(streampos, streampos, FALSE)) { | |
| 600 return FALSE; | |
| 601 } | |
| 602 return TRUE; | |
| 603 } | |
| 604 FX_BOOL CPDF_Parser::LoadAllCrossRefV5(FX_FILESIZE xrefpos) | |
| 605 { | |
| 606 if (!LoadCrossRefV5(xrefpos, xrefpos, TRUE)) { | |
| 607 return FALSE; | |
| 608 } | |
| 609 while (xrefpos) | |
| 610 if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) { | |
| 611 return FALSE; | |
| 612 } | |
| 613 m_ObjectStreamMap.InitHashTable(101, FALSE); | |
| 614 m_bXRefStream = TRUE; | |
| 615 return TRUE; | |
| 616 } | |
| 617 FX_BOOL CPDF_Parser::RebuildCrossRef() | |
| 618 { | |
| 619 m_CrossRef.RemoveAll(); | |
| 620 m_V5Type.RemoveAll(); | |
| 621 m_SortedOffset.RemoveAll(); | |
| 622 m_ObjVersion.RemoveAll(); | |
| 623 if (m_pTrailer) { | |
| 624 m_pTrailer->Release(); | |
| 625 m_pTrailer = NULL; | |
| 626 } | |
| 627 int32_t status = 0; | |
| 628 int32_t inside_index = 0; | |
| 629 FX_DWORD objnum = 0, gennum = 0; | |
| 630 int32_t depth = 0; | |
| 631 uint8_t* buffer = FX_Alloc(uint8_t, 4096); | |
| 632 FX_FILESIZE pos = m_Syntax.m_HeaderOffset; | |
| 633 FX_FILESIZE start_pos = 0, start_pos1 = 0; | |
| 634 FX_FILESIZE last_obj = -1, last_xref = -1, last_trailer = -1; | |
| 635 while (pos < m_Syntax.m_FileLen) { | |
| 636 FX_BOOL bOverFlow = FALSE; | |
| 637 FX_DWORD size = (FX_DWORD)(m_Syntax.m_FileLen - pos); | |
| 638 if (size > 4096) { | |
| 639 size = 4096; | |
| 640 } | |
| 641 if (!m_Syntax.m_pFileAccess->ReadBlock(buffer, pos, size)) { | |
| 642 break; | |
| 643 } | |
| 644 for (FX_DWORD i = 0; i < size; i ++) { | |
| 645 uint8_t byte = buffer[i]; | |
| 646 switch (status) { | |
| 647 case 0: | |
| 648 if (PDF_CharType[byte] == 'W') { | |
| 649 status = 1; | |
| 650 } | |
| 651 if (byte <= '9' && byte >= '0') { | |
| 652 --i; | |
| 653 status = 1; | |
| 654 } | |
| 655 if (byte == '%') { | |
| 656 inside_index = 0; | |
| 657 status = 9; | |
| 658 } | |
| 659 if (byte == '(') { | |
| 660 status = 10; | |
| 661 depth = 1; | |
| 662 } | |
| 663 if (byte == '<') { | |
| 664 inside_index = 1; | |
| 665 status = 11; | |
| 666 } | |
| 667 if (byte == '\\') { | |
| 668 status = 13; | |
| 669 } | |
| 670 if (byte == 't') { | |
| 671 status = 7; | |
| 672 inside_index = 1; | |
| 673 } | |
| 674 break; | |
| 675 case 1: | |
| 676 if (PDF_CharType[byte] == 'W') { | |
| 677 break; | |
| 678 } else if (byte <= '9' && byte >= '0') { | |
| 679 start_pos = pos + i; | |
| 680 status = 2; | |
| 681 objnum = byte - '0'; | |
| 682 } else if (byte == 't') { | |
| 683 status = 7; | |
| 684 inside_index = 1; | |
| 685 } else if (byte == 'x') { | |
| 686 status = 8; | |
| 687 inside_index = 1; | |
| 688 } else { | |
| 689 --i; | |
| 690 status = 0; | |
| 691 } | |
| 692 break; | |
| 693 case 2: | |
| 694 if (byte <= '9' && byte >= '0') { | |
| 695 objnum = objnum * 10 + byte - '0'; | |
| 696 break; | |
| 697 } else if (PDF_CharType[byte] == 'W') { | |
| 698 status = 3; | |
| 699 } else { | |
| 700 --i; | |
| 701 status = 14; | |
| 702 inside_index = 0; | |
| 703 } | |
| 704 break; | |
| 705 case 3: | |
| 706 if (byte <= '9' && byte >= '0') { | |
| 707 start_pos1 = pos + i; | |
| 708 status = 4; | |
| 709 gennum = byte - '0'; | |
| 710 } else if (PDF_CharType[byte] == 'W') { | |
| 711 break; | |
| 712 } else if (byte == 't') { | |
| 713 status = 7; | |
| 714 inside_index = 1; | |
| 715 } else { | |
| 716 --i; | |
| 717 status = 0; | |
| 718 } | |
| 719 break; | |
| 720 case 4: | |
| 721 if (byte <= '9' && byte >= '0') { | |
| 722 gennum = gennum * 10 + byte - '0'; | |
| 723 break; | |
| 724 } else if (PDF_CharType[byte] == 'W') { | |
| 725 status = 5; | |
| 726 } else { | |
| 727 --i; | |
| 728 status = 0; | |
| 729 } | |
| 730 break; | |
| 731 case 5: | |
| 732 if (byte == 'o') { | |
| 733 status = 6; | |
| 734 inside_index = 1; | |
| 735 } else if (PDF_CharType[byte] == 'W') { | |
| 736 break; | |
| 737 } else if (byte <= '9' && byte >= '0') { | |
| 738 objnum = gennum; | |
| 739 gennum = byte - '0'; | |
| 740 start_pos = start_pos1; | |
| 741 start_pos1 = pos + i; | |
| 742 status = 4; | |
| 743 } else if (byte == 't') { | |
| 744 status = 7; | |
| 745 inside_index = 1; | |
| 746 } else { | |
| 747 --i; | |
| 748 status = 0; | |
| 749 } | |
| 750 break; | |
| 751 case 6: | |
| 752 switch (inside_index) { | |
| 753 case 1: | |
| 754 if (byte != 'b') { | |
| 755 --i; | |
| 756 status = 0; | |
| 757 } else { | |
| 758 inside_index ++; | |
| 759 } | |
| 760 break; | |
| 761 case 2: | |
| 762 if (byte != 'j') { | |
| 763 --i; | |
| 764 status = 0; | |
| 765 } else { | |
| 766 inside_index ++; | |
| 767 } | |
| 768 break; | |
| 769 case 3: | |
| 770 if (PDF_CharType[byte] == 'W' || PDF_CharType[byte]
== 'D') { | |
| 771 if (objnum > 0x1000000) { | |
| 772 status = 0; | |
| 773 break; | |
| 774 } | |
| 775 FX_FILESIZE obj_pos = start_pos - m_Syntax.m_Hea
derOffset; | |
| 776 last_obj = start_pos; | |
| 777 void* pResult = FXSYS_bsearch(&obj_pos, m_Sorted
Offset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSiz
e); | |
| 778 if (pResult == NULL) { | |
| 779 m_SortedOffset.Add(obj_pos); | |
| 780 } | |
| 781 FX_FILESIZE obj_end = 0; | |
| 782 CPDF_Object *pObject = ParseIndirectObjectAtBySt
rict(m_pDocument, obj_pos, objnum, NULL, &obj_end); | |
| 783 if (pObject) { | |
| 784 int iType = pObject->GetType(); | |
| 785 if (iType == PDFOBJ_STREAM) { | |
| 786 CPDF_Stream* pStream = (CPDF_Stream*)pOb
ject; | |
| 787 CPDF_Dictionary* pDict = pStream->GetDic
t(); | |
| 788 if (pDict) { | |
| 789 if (pDict->KeyExist(FX_BSTRC("Type")
)) { | |
| 790 CFX_ByteString bsValue = pDict->
GetString(FX_BSTRC("Type")); | |
| 791 if (bsValue == FX_BSTRC("XRef")
&& pDict->KeyExist(FX_BSTRC("Size"))) { | |
| 792 CPDF_Object* pRoot = pDict->
GetElement(FX_BSTRC("Root")); | |
| 793 if (pRoot && pRoot->GetDict(
) && pRoot->GetDict()->GetElement(FX_BSTRC("Pages"))) { | |
| 794 if (m_pTrailer) { | |
| 795 m_pTrailer->Release(
); | |
| 796 } | |
| 797 m_pTrailer = (CPDF_Dicti
onary*)pDict->Clone(); | |
| 798 } | |
| 799 } | |
| 800 } | |
| 801 } | |
| 802 } | |
| 803 } | |
| 804 FX_FILESIZE offset = 0; | |
| 805 m_Syntax.RestorePos(obj_pos); | |
| 806 offset = m_Syntax.FindTag(FX_BSTRC("obj"), 0); | |
| 807 if (offset == -1) { | |
| 808 offset = 0; | |
| 809 } else { | |
| 810 offset += 3; | |
| 811 } | |
| 812 FX_FILESIZE nLen = obj_end - obj_pos - offset; | |
| 813 if ((FX_DWORD)nLen > size - i) { | |
| 814 pos = obj_end + m_Syntax.m_HeaderOffset; | |
| 815 bOverFlow = TRUE; | |
| 816 } else { | |
| 817 i += (FX_DWORD)nLen; | |
| 818 } | |
| 819 if (m_CrossRef.GetSize() > (int32_t)objnum && m_
CrossRef[objnum]) { | |
| 820 if (pObject) { | |
| 821 FX_DWORD oldgen = m_ObjVersion.GetAt(obj
num); | |
| 822 m_CrossRef[objnum] = obj_pos; | |
| 823 m_ObjVersion.SetAt(objnum, (int16_t)genn
um); | |
| 824 if (oldgen != gennum) { | |
| 825 m_bVersionUpdated = TRUE; | |
| 826 } | |
| 827 } | |
| 828 } else { | |
| 829 m_CrossRef.SetAtGrow(objnum, obj_pos); | |
| 830 m_V5Type.SetAtGrow(objnum, 1); | |
| 831 m_ObjVersion.SetAtGrow(objnum, (int16_t)genn
um); | |
| 832 } | |
| 833 if (pObject) { | |
| 834 pObject->Release(); | |
| 835 } | |
| 836 } | |
| 837 --i; | |
| 838 status = 0; | |
| 839 break; | |
| 840 } | |
| 841 break; | |
| 842 case 7: | |
| 843 if (inside_index == 7) { | |
| 844 if (PDF_CharType[byte] == 'W' || PDF_CharType[byte] == '
D') { | |
| 845 last_trailer = pos + i - 7; | |
| 846 m_Syntax.RestorePos(pos + i - m_Syntax.m_HeaderOffse
t); | |
| 847 CPDF_Object* pObj = m_Syntax.GetObject(m_pDocument,
0, 0, 0); | |
| 848 if (pObj) { | |
| 849 if (pObj->GetType() != PDFOBJ_DICTIONARY && pObj
->GetType() != PDFOBJ_STREAM) { | |
| 850 pObj->Release(); | |
| 851 } else { | |
| 852 CPDF_Dictionary* pTrailer = NULL; | |
| 853 if (pObj->GetType() == PDFOBJ_STREAM) { | |
| 854 pTrailer = ((CPDF_Stream*)pObj)->GetDict
(); | |
| 855 } else { | |
| 856 pTrailer = (CPDF_Dictionary*)pObj; | |
| 857 } | |
| 858 if (pTrailer) { | |
| 859 if (m_pTrailer) { | |
| 860 CPDF_Object* pRoot = pTrailer->GetEl
ement(FX_BSTRC("Root")); | |
| 861 if (pRoot == NULL || (pRoot->GetType
() == PDFOBJ_REFERENCE && | |
| 862 (FX_DWORD)m_Cr
ossRef.GetSize() > ((CPDF_Reference*)pRoot)->GetRefObjNum() && | |
| 863 m_CrossRef.Get
At(((CPDF_Reference*)pRoot)->GetRefObjNum()) != 0)) { | |
| 864 FX_POSITION pos = pTrailer->GetS
tartPos(); | |
| 865 while (pos) { | |
| 866 CFX_ByteString key; | |
| 867 CPDF_Object* pObj = pTrailer
->GetNextElement(pos, key); | |
| 868 m_pTrailer->SetAt(key, pObj-
>Clone(), m_pDocument); | |
| 869 } | |
| 870 pObj->Release(); | |
| 871 } else { | |
| 872 pObj->Release(); | |
| 873 } | |
| 874 } else { | |
| 875 if (pObj->GetType() == PDFOBJ_STREAM
) { | |
| 876 m_pTrailer = (CPDF_Dictionary*)p
Trailer->Clone(); | |
| 877 pObj->Release(); | |
| 878 } else { | |
| 879 m_pTrailer = pTrailer; | |
| 880 } | |
| 881 FX_FILESIZE dwSavePos = m_Syntax.Sav
ePos(); | |
| 882 CFX_ByteString strWord = m_Syntax.Ge
tKeyword(); | |
| 883 if (!strWord.Compare(FX_BSTRC("start
xref"))) { | |
| 884 FX_BOOL bNumber = FALSE; | |
| 885 CFX_ByteString bsOffset = m_Synt
ax.GetNextWord(bNumber); | |
| 886 if (bNumber) { | |
| 887 m_LastXRefOffset = FXSYS_ato
i(bsOffset); | |
| 888 } | |
| 889 } | |
| 890 m_Syntax.RestorePos(dwSavePos); | |
| 891 } | |
| 892 } else { | |
| 893 pObj->Release(); | |
| 894 } | |
| 895 } | |
| 896 } | |
| 897 } | |
| 898 --i; | |
| 899 status = 0; | |
| 900 } else if (byte == "trailer"[inside_index]) { | |
| 901 inside_index ++; | |
| 902 } else { | |
| 903 --i; | |
| 904 status = 0; | |
| 905 } | |
| 906 break; | |
| 907 case 8: | |
| 908 if (inside_index == 4) { | |
| 909 last_xref = pos + i - 4; | |
| 910 status = 1; | |
| 911 } else if (byte == "xref"[inside_index]) { | |
| 912 inside_index ++; | |
| 913 } else { | |
| 914 --i; | |
| 915 status = 0; | |
| 916 } | |
| 917 break; | |
| 918 case 9: | |
| 919 if (byte == '\r' || byte == '\n') { | |
| 920 status = 0; | |
| 921 } | |
| 922 break; | |
| 923 case 10: | |
| 924 if (byte == ')') { | |
| 925 if (depth > 0) { | |
| 926 depth--; | |
| 927 } | |
| 928 } else if (byte == '(') { | |
| 929 depth++; | |
| 930 } | |
| 931 if (!depth) { | |
| 932 status = 0; | |
| 933 } | |
| 934 break; | |
| 935 case 11: | |
| 936 if (byte == '<' && inside_index == 1) { | |
| 937 status = 12; | |
| 938 } else if (byte == '>') { | |
| 939 status = 0; | |
| 940 } | |
| 941 inside_index = 0; | |
| 942 break; | |
| 943 case 12: | |
| 944 --i; | |
| 945 status = 0; | |
| 946 break; | |
| 947 case 13: | |
| 948 if (PDF_CharType[byte] == 'D' || PDF_CharType[byte] == 'W')
{ | |
| 949 --i; | |
| 950 status = 0; | |
| 951 } | |
| 952 break; | |
| 953 case 14: | |
| 954 if (PDF_CharType[byte] == 'W') { | |
| 955 status = 0; | |
| 956 } else if (byte == '%' || byte == '(' || byte == '<' || byte
== '\\') { | |
| 957 status = 0; | |
| 958 --i; | |
| 959 } else if (inside_index == 6) { | |
| 960 status = 0; | |
| 961 --i; | |
| 962 } else if (byte == "endobj"[inside_index]) { | |
| 963 inside_index++; | |
| 964 } | |
| 965 break; | |
| 966 } | |
| 967 if (bOverFlow) { | |
| 968 size = 0; | |
| 969 break; | |
| 970 } | |
| 971 } | |
| 972 pos += size; | |
| 973 } | |
| 974 if (last_xref != -1 && last_xref > last_obj) { | |
| 975 last_trailer = last_xref; | |
| 976 } else if (last_trailer == -1 || last_xref < last_obj) { | |
| 977 last_trailer = m_Syntax.m_FileLen; | |
| 978 } | |
| 979 FX_FILESIZE offset = last_trailer - m_Syntax.m_HeaderOffset; | |
| 980 void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOff
set.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); | |
| 981 if (pResult == NULL) { | |
| 982 m_SortedOffset.Add(offset); | |
| 983 } | |
| 984 FX_Free(buffer); | |
| 985 return TRUE; | |
| 986 } | |
| 987 static FX_DWORD _GetVarInt(const uint8_t* p, int32_t n) | |
| 988 { | |
| 989 FX_DWORD result = 0; | |
| 990 for (int32_t i = 0; i < n; i ++) { | |
| 991 result = result * 256 + p[i]; | |
| 992 } | |
| 993 return result; | |
| 994 } | |
| 995 FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE pos, FX_FILESIZE& prev, FX_BOOL
bMainXRef) | |
| 996 { | |
| 997 CPDF_Stream* pStream = (CPDF_Stream*)ParseIndirectObjectAt(m_pDocument, pos,
0, NULL); | |
| 998 if (!pStream) { | |
| 999 return FALSE; | |
| 1000 } | |
| 1001 if (m_pDocument) { | |
| 1002 CPDF_Dictionary * pDict = m_pDocument->GetRoot(); | |
| 1003 if (!pDict || pDict->GetObjNum() != pStream->m_ObjNum) { | |
| 1004 m_pDocument->InsertIndirectObject(pStream->m_ObjNum, pStream); | |
| 1005 } else { | 1337 } else { |
| 1006 if (pStream->GetType() == PDFOBJ_STREAM) { | 1338 syntax.GetDirectNum(); // Skip nextnum. |
| 1007 pStream->Release(); | 1339 FX_DWORD nextoff = syntax.GetDirectNum(); |
| 1008 } | 1340 size = nextoff - thisoff; |
| 1009 return FALSE; | 1341 } |
| 1010 } | 1342 pBuffer = FX_Alloc(uint8_t, size); |
| 1011 } | 1343 FXSYS_memcpy(pBuffer, pData + thisoff + offset, size); |
| 1012 if (pStream->GetType() != PDFOBJ_STREAM) { | 1344 return; |
| 1013 return FALSE; | 1345 } |
| 1014 } | 1346 n--; |
| 1015 prev = pStream->GetDict()->GetInteger(FX_BSTRC("Prev")); | 1347 } |
| 1016 int32_t size = pStream->GetDict()->GetInteger(FX_BSTRC("Size")); | 1348 return; |
| 1017 if (size < 0) { | 1349 } |
| 1018 pStream->Release(); | 1350 if (m_V5Type[objnum] == 1) { |
| 1019 return FALSE; | |
| 1020 } | |
| 1021 if (bMainXRef) { | |
| 1022 m_pTrailer = (CPDF_Dictionary*)pStream->GetDict()->Clone(); | |
| 1023 m_CrossRef.SetSize(size); | |
| 1024 if (m_V5Type.SetSize(size)) { | |
| 1025 FXSYS_memset(m_V5Type.GetData(), 0, size); | |
| 1026 } | |
| 1027 } else { | |
| 1028 m_Trailers.Add((CPDF_Dictionary*)pStream->GetDict()->Clone()); | |
| 1029 } | |
| 1030 std::vector<std::pair<int32_t, int32_t> > arrIndex; | |
| 1031 CPDF_Array* pArray = pStream->GetDict()->GetArray(FX_BSTRC("Index")); | |
| 1032 if (pArray) { | |
| 1033 FX_DWORD nPairSize = pArray->GetCount() / 2; | |
| 1034 for (FX_DWORD i = 0; i < nPairSize; i++) { | |
| 1035 CPDF_Object* pStartNumObj = pArray->GetElement(i * 2); | |
| 1036 CPDF_Object* pCountObj = pArray->GetElement(i * 2 + 1); | |
| 1037 if (pStartNumObj && pStartNumObj->GetType() == PDFOBJ_NUMBER | |
| 1038 && pCountObj && pCountObj->GetType() == PDFOBJ_NUMBER) { | |
| 1039 int nStartNum = pStartNumObj->GetInteger(); | |
| 1040 int nCount = pCountObj->GetInteger(); | |
| 1041 if (nStartNum >= 0 && nCount > 0) { | |
| 1042 arrIndex.push_back(std::make_pair(nStartNum, nCount)); | |
| 1043 } | |
| 1044 } | |
| 1045 } | |
| 1046 } | |
| 1047 if (arrIndex.size() == 0) { | |
| 1048 arrIndex.push_back(std::make_pair(0, size)); | |
| 1049 } | |
| 1050 pArray = pStream->GetDict()->GetArray(FX_BSTRC("W")); | |
| 1051 if (pArray == NULL) { | |
| 1052 pStream->Release(); | |
| 1053 return FALSE; | |
| 1054 } | |
| 1055 CFX_DWordArray WidthArray; | |
| 1056 FX_SAFE_DWORD dwAccWidth = 0; | |
| 1057 for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) { | |
| 1058 WidthArray.Add(pArray->GetInteger(i)); | |
| 1059 dwAccWidth += WidthArray[i]; | |
| 1060 } | |
| 1061 if (!dwAccWidth.IsValid() || WidthArray.GetSize() < 3) { | |
| 1062 pStream->Release(); | |
| 1063 return FALSE; | |
| 1064 } | |
| 1065 FX_DWORD totalWidth = dwAccWidth.ValueOrDie(); | |
| 1066 CPDF_StreamAcc acc; | |
| 1067 acc.LoadAllData(pStream); | |
| 1068 const uint8_t* pData = acc.GetData(); | |
| 1069 FX_DWORD dwTotalSize = acc.GetSize(); | |
| 1070 FX_DWORD segindex = 0; | |
| 1071 for (FX_DWORD i = 0; i < arrIndex.size(); i ++) { | |
| 1072 int32_t startnum = arrIndex[i].first; | |
| 1073 if (startnum < 0) { | |
| 1074 continue; | |
| 1075 } | |
| 1076 m_dwXrefStartObjNum = pdfium::base::checked_cast<FX_DWORD, int32_t> (sta
rtnum); | |
| 1077 FX_DWORD count = pdfium::base::checked_cast<FX_DWORD, int32_t> (arrIndex
[i].second); | |
| 1078 FX_SAFE_DWORD dwCaculatedSize = segindex; | |
| 1079 dwCaculatedSize += count; | |
| 1080 dwCaculatedSize *= totalWidth; | |
| 1081 if (!dwCaculatedSize.IsValid() || dwCaculatedSize.ValueOrDie() > dwTotal
Size) { | |
| 1082 continue; | |
| 1083 } | |
| 1084 const uint8_t* segstart = pData + segindex * totalWidth; | |
| 1085 FX_SAFE_DWORD dwMaxObjNum = startnum; | |
| 1086 dwMaxObjNum += count; | |
| 1087 FX_DWORD dwV5Size = pdfium::base::checked_cast<FX_DWORD, int32_t> (m_V5T
ype.GetSize()); | |
| 1088 if (!dwMaxObjNum.IsValid() || dwMaxObjNum.ValueOrDie() > dwV5Size) { | |
| 1089 continue; | |
| 1090 } | |
| 1091 for (FX_DWORD j = 0; j < count; j ++) { | |
| 1092 int32_t type = 1; | |
| 1093 const uint8_t* entrystart = segstart + j * totalWidth; | |
| 1094 if (WidthArray[0]) { | |
| 1095 type = _GetVarInt(entrystart, WidthArray[0]); | |
| 1096 } | |
| 1097 if (m_V5Type[startnum + j] == 255) { | |
| 1098 FX_FILESIZE offset = _GetVarInt(entrystart + WidthArray[0], Widt
hArray[1]); | |
| 1099 m_CrossRef[startnum + j] = offset; | |
| 1100 void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(),
m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); | |
| 1101 if (pResult == NULL) { | |
| 1102 m_SortedOffset.Add(offset); | |
| 1103 } | |
| 1104 continue; | |
| 1105 } | |
| 1106 if (m_V5Type[startnum + j]) { | |
| 1107 continue; | |
| 1108 } | |
| 1109 m_V5Type[startnum + j] = type; | |
| 1110 if (type == 0) { | |
| 1111 m_CrossRef[startnum + j] = 0; | |
| 1112 } else { | |
| 1113 FX_FILESIZE offset = _GetVarInt(entrystart + WidthArray[0], Widt
hArray[1]); | |
| 1114 m_CrossRef[startnum + j] = offset; | |
| 1115 if (type == 1) { | |
| 1116 void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetDat
a(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); | |
| 1117 if (pResult == NULL) { | |
| 1118 m_SortedOffset.Add(offset); | |
| 1119 } | |
| 1120 } else { | |
| 1121 if (offset < 0 || offset >= m_V5Type.GetSize()) { | |
| 1122 pStream->Release(); | |
| 1123 return FALSE; | |
| 1124 } | |
| 1125 m_V5Type[offset] = 255; | |
| 1126 } | |
| 1127 } | |
| 1128 } | |
| 1129 segindex += count; | |
| 1130 } | |
| 1131 pStream->Release(); | |
| 1132 return TRUE; | |
| 1133 } | |
| 1134 CPDF_Array* CPDF_Parser::GetIDArray() | |
| 1135 { | |
| 1136 CPDF_Object* pID = m_pTrailer ? m_pTrailer->GetElement(FX_BSTRC("ID")) : NUL
L; | |
| 1137 if (pID == NULL) { | |
| 1138 return NULL; | |
| 1139 } | |
| 1140 if (pID->GetType() == PDFOBJ_REFERENCE) { | |
| 1141 pID = ParseIndirectObject(NULL, ((CPDF_Reference*)pID)->GetRefObjNum()); | |
| 1142 m_pTrailer->SetAt(FX_BSTRC("ID"), pID); | |
| 1143 } | |
| 1144 if (pID == NULL || pID->GetType() != PDFOBJ_ARRAY) { | |
| 1145 return NULL; | |
| 1146 } | |
| 1147 return (CPDF_Array*)pID; | |
| 1148 } | |
| 1149 FX_DWORD CPDF_Parser::GetRootObjNum() | |
| 1150 { | |
| 1151 CPDF_Object* pRef = m_pTrailer ? m_pTrailer->GetElement(FX_BSTRC("Root")) :
NULL; | |
| 1152 if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) { | |
| 1153 return 0; | |
| 1154 } | |
| 1155 return ((CPDF_Reference*) pRef)->GetRefObjNum(); | |
| 1156 } | |
| 1157 FX_DWORD CPDF_Parser::GetInfoObjNum() | |
| 1158 { | |
| 1159 CPDF_Object* pRef = m_pTrailer ? m_pTrailer->GetElement(FX_BSTRC("Info")) :
NULL; | |
| 1160 if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) { | |
| 1161 return 0; | |
| 1162 } | |
| 1163 return ((CPDF_Reference*) pRef)->GetRefObjNum(); | |
| 1164 } | |
| 1165 FX_BOOL CPDF_Parser::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm) | |
| 1166 { | |
| 1167 bForm = FALSE; | |
| 1168 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) { | |
| 1169 return TRUE; | |
| 1170 } | |
| 1171 if (m_V5Type[objnum] == 0) { | |
| 1172 return TRUE; | |
| 1173 } | |
| 1174 if (m_V5Type[objnum] == 2) { | |
| 1175 return TRUE; | |
| 1176 } | |
| 1177 FX_FILESIZE pos = m_CrossRef[objnum]; | 1351 FX_FILESIZE pos = m_CrossRef[objnum]; |
| 1178 void* pResult = FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset
.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); | 1352 if (pos == 0) { |
| 1179 if (pResult == NULL) { | 1353 return; |
| 1180 return TRUE; | 1354 } |
| 1181 } | |
| 1182 if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)m_SortedOffset.GetData() == m_Sort
edOffset.GetSize() - 1) { | |
| 1183 return FALSE; | |
| 1184 } | |
| 1185 FX_FILESIZE size = ((FX_FILESIZE*)pResult)[1] - pos; | |
| 1186 FX_FILESIZE SavedPos = m_Syntax.SavePos(); | |
| 1187 m_Syntax.RestorePos(pos); | |
| 1188 bForm = m_Syntax.SearchMultiWord(FX_BSTRC("/Form\0stream"), TRUE, size) == 0
; | |
| 1189 m_Syntax.RestorePos(SavedPos); | |
| 1190 return TRUE; | |
| 1191 } | |
| 1192 CPDF_Object* CPDF_Parser::ParseIndirectObject(CPDF_IndirectObjects* pObjList, FX
_DWORD objnum, PARSE_CONTEXT* pContext) | |
| 1193 { | |
| 1194 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) { | |
| 1195 return NULL; | |
| 1196 } | |
| 1197 if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) { | |
| 1198 FX_FILESIZE pos = m_CrossRef[objnum]; | |
| 1199 if (pos <= 0) { | |
| 1200 return NULL; | |
| 1201 } | |
| 1202 return ParseIndirectObjectAt(pObjList, pos, objnum, pContext); | |
| 1203 } | |
| 1204 if (m_V5Type[objnum] == 2) { | |
| 1205 CPDF_StreamAcc* pObjStream = GetObjectStream((FX_DWORD)m_CrossRef[objnum
]); | |
| 1206 if (pObjStream == NULL) { | |
| 1207 return NULL; | |
| 1208 } | |
| 1209 int32_t n = pObjStream->GetDict()->GetInteger(FX_BSTRC("N")); | |
| 1210 int32_t offset = pObjStream->GetDict()->GetInteger(FX_BSTRC("First")); | |
| 1211 CPDF_SyntaxParser syntax; | |
| 1212 CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream((uint8_t*)pO
bjStream->GetData(), (size_t)pObjStream->GetSize(), FALSE)); | |
| 1213 syntax.InitParser(file.Get(), 0); | |
| 1214 CPDF_Object* pRet = NULL; | |
| 1215 while (n) { | |
| 1216 FX_DWORD thisnum = syntax.GetDirectNum(); | |
| 1217 FX_DWORD thisoff = syntax.GetDirectNum(); | |
| 1218 if (thisnum == objnum) { | |
| 1219 syntax.RestorePos(offset + thisoff); | |
| 1220 pRet = syntax.GetObject(pObjList, 0, 0, pContext); | |
| 1221 break; | |
| 1222 } | |
| 1223 n --; | |
| 1224 } | |
| 1225 return pRet; | |
| 1226 } | |
| 1227 return NULL; | |
| 1228 } | |
| 1229 CPDF_StreamAcc* CPDF_Parser::GetObjectStream(FX_DWORD objnum) | |
| 1230 { | |
| 1231 CPDF_StreamAcc* pStreamAcc = NULL; | |
| 1232 if (m_ObjectStreamMap.Lookup((void*)(uintptr_t)objnum, (void*&)pStreamAcc))
{ | |
| 1233 return pStreamAcc; | |
| 1234 } | |
| 1235 const CPDF_Stream* pStream = m_pDocument ? (CPDF_Stream*)m_pDocument->GetInd
irectObject(objnum) : NULL; | |
| 1236 if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM) { | |
| 1237 return NULL; | |
| 1238 } | |
| 1239 pStreamAcc = new CPDF_StreamAcc; | |
| 1240 pStreamAcc->LoadAllData(pStream); | |
| 1241 m_ObjectStreamMap.SetAt((void*)(uintptr_t)objnum, pStreamAcc); | |
| 1242 return pStreamAcc; | |
| 1243 } | |
| 1244 FX_FILESIZE CPDF_Parser::GetObjectSize(FX_DWORD objnum) | |
| 1245 { | |
| 1246 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) { | |
| 1247 return 0; | |
| 1248 } | |
| 1249 if (m_V5Type[objnum] == 2) { | |
| 1250 objnum = (FX_DWORD)m_CrossRef[objnum]; | |
| 1251 } | |
| 1252 if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) { | |
| 1253 FX_FILESIZE offset = m_CrossRef[objnum]; | |
| 1254 if (offset == 0) { | |
| 1255 return 0; | |
| 1256 } | |
| 1257 void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_Sorte
dOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); | |
| 1258 if (pResult == NULL) { | |
| 1259 return 0; | |
| 1260 } | |
| 1261 if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)m_SortedOffset.GetData() == m_
SortedOffset.GetSize() - 1) { | |
| 1262 return 0; | |
| 1263 } | |
| 1264 return ((FX_FILESIZE*)pResult)[1] - offset; | |
| 1265 } | |
| 1266 return 0; | |
| 1267 } | |
| 1268 void CPDF_Parser::GetIndirectBinary(FX_DWORD objnum, uint8_t*& pBuffer, FX_DWORD
& size) | |
| 1269 { | |
| 1270 pBuffer = NULL; | |
| 1271 size = 0; | |
| 1272 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) { | |
| 1273 return; | |
| 1274 } | |
| 1275 if (m_V5Type[objnum] == 2) { | |
| 1276 CPDF_StreamAcc* pObjStream = GetObjectStream((FX_DWORD)m_CrossRef[objnum
]); | |
| 1277 if (pObjStream == NULL) { | |
| 1278 return; | |
| 1279 } | |
| 1280 int32_t n = pObjStream->GetDict()->GetInteger(FX_BSTRC("N")); | |
| 1281 int32_t offset = pObjStream->GetDict()->GetInteger(FX_BSTRC("First")); | |
| 1282 CPDF_SyntaxParser syntax; | |
| 1283 const uint8_t* pData = pObjStream->GetData(); | |
| 1284 FX_DWORD totalsize = pObjStream->GetSize(); | |
| 1285 CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream((uint8_t*)pD
ata, (size_t)totalsize, FALSE)); | |
| 1286 syntax.InitParser(file.Get(), 0); | |
| 1287 while (n) { | |
| 1288 FX_DWORD thisnum = syntax.GetDirectNum(); | |
| 1289 FX_DWORD thisoff = syntax.GetDirectNum(); | |
| 1290 if (thisnum == objnum) { | |
| 1291 if (n == 1) { | |
| 1292 size = totalsize - (thisoff + offset); | |
| 1293 } else { | |
| 1294 syntax.GetDirectNum(); // Skip nextnum. | |
| 1295 FX_DWORD nextoff = syntax.GetDirectNum(); | |
| 1296 size = nextoff - thisoff; | |
| 1297 } | |
| 1298 pBuffer = FX_Alloc(uint8_t, size); | |
| 1299 FXSYS_memcpy(pBuffer, pData + thisoff + offset, size); | |
| 1300 return; | |
| 1301 } | |
| 1302 n --; | |
| 1303 } | |
| 1304 return; | |
| 1305 } | |
| 1306 if (m_V5Type[objnum] == 1) { | |
| 1307 FX_FILESIZE pos = m_CrossRef[objnum]; | |
| 1308 if (pos == 0) { | |
| 1309 return; | |
| 1310 } | |
| 1311 FX_FILESIZE SavedPos = m_Syntax.SavePos(); | |
| 1312 m_Syntax.RestorePos(pos); | |
| 1313 FX_BOOL bIsNumber; | |
| 1314 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); | |
| 1315 if (!bIsNumber) { | |
| 1316 m_Syntax.RestorePos(SavedPos); | |
| 1317 return; | |
| 1318 } | |
| 1319 FX_DWORD parser_objnum = FXSYS_atoi(word); | |
| 1320 if (parser_objnum && parser_objnum != objnum) { | |
| 1321 m_Syntax.RestorePos(SavedPos); | |
| 1322 return; | |
| 1323 } | |
| 1324 word = m_Syntax.GetNextWord(bIsNumber); | |
| 1325 if (!bIsNumber) { | |
| 1326 m_Syntax.RestorePos(SavedPos); | |
| 1327 return; | |
| 1328 } | |
| 1329 if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) { | |
| 1330 m_Syntax.RestorePos(SavedPos); | |
| 1331 return; | |
| 1332 } | |
| 1333 void* pResult = FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOf
fset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); | |
| 1334 if (pResult == NULL) { | |
| 1335 m_Syntax.RestorePos(SavedPos); | |
| 1336 return; | |
| 1337 } | |
| 1338 FX_FILESIZE nextoff = ((FX_FILESIZE*)pResult)[1]; | |
| 1339 FX_BOOL bNextOffValid = FALSE; | |
| 1340 if (nextoff != pos) { | |
| 1341 m_Syntax.RestorePos(nextoff); | |
| 1342 word = m_Syntax.GetNextWord(bIsNumber); | |
| 1343 if (word == FX_BSTRC("xref")) { | |
| 1344 bNextOffValid = TRUE; | |
| 1345 } else if (bIsNumber) { | |
| 1346 word = m_Syntax.GetNextWord(bIsNumber); | |
| 1347 if (bIsNumber && m_Syntax.GetKeyword() == FX_BSTRC("obj")) { | |
| 1348 bNextOffValid = TRUE; | |
| 1349 } | |
| 1350 } | |
| 1351 } | |
| 1352 if (!bNextOffValid) { | |
| 1353 m_Syntax.RestorePos(pos); | |
| 1354 while (1) { | |
| 1355 if (m_Syntax.GetKeyword() == FX_BSTRC("endobj")) { | |
| 1356 break; | |
| 1357 } | |
| 1358 if (m_Syntax.SavePos() == m_Syntax.m_FileLen) { | |
| 1359 break; | |
| 1360 } | |
| 1361 } | |
| 1362 nextoff = m_Syntax.SavePos(); | |
| 1363 } | |
| 1364 size = (FX_DWORD)(nextoff - pos); | |
| 1365 pBuffer = FX_Alloc(uint8_t, size); | |
| 1366 m_Syntax.RestorePos(pos); | |
| 1367 m_Syntax.ReadBlock(pBuffer, size); | |
| 1368 m_Syntax.RestorePos(SavedPos); | |
| 1369 } | |
| 1370 } | |
| 1371 CPDF_Object* CPDF_Parser::ParseIndirectObjectAt(CPDF_IndirectObjects* pObjList,
FX_FILESIZE pos, FX_DWORD objnum, | |
| 1372 PARSE_CONTEXT* pContext) | |
| 1373 { | |
| 1374 FX_FILESIZE SavedPos = m_Syntax.SavePos(); | 1355 FX_FILESIZE SavedPos = m_Syntax.SavePos(); |
| 1375 m_Syntax.RestorePos(pos); | 1356 m_Syntax.RestorePos(pos); |
| 1376 FX_BOOL bIsNumber; | 1357 FX_BOOL bIsNumber; |
| 1377 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); | 1358 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); |
| 1378 if (!bIsNumber) { | 1359 if (!bIsNumber) { |
| 1379 m_Syntax.RestorePos(SavedPos); | 1360 m_Syntax.RestorePos(SavedPos); |
| 1380 return NULL; | 1361 return; |
| 1381 } | 1362 } |
| 1382 FX_FILESIZE objOffset = m_Syntax.SavePos(); | |
| 1383 objOffset -= word.GetLength(); | |
| 1384 FX_DWORD parser_objnum = FXSYS_atoi(word); | 1363 FX_DWORD parser_objnum = FXSYS_atoi(word); |
| 1385 if (objnum && parser_objnum != objnum) { | 1364 if (parser_objnum && parser_objnum != objnum) { |
| 1386 m_Syntax.RestorePos(SavedPos); | 1365 m_Syntax.RestorePos(SavedPos); |
| 1387 return NULL; | 1366 return; |
| 1388 } | 1367 } |
| 1389 word = m_Syntax.GetNextWord(bIsNumber); | 1368 word = m_Syntax.GetNextWord(bIsNumber); |
| 1390 if (!bIsNumber) { | 1369 if (!bIsNumber) { |
| 1391 m_Syntax.RestorePos(SavedPos); | 1370 m_Syntax.RestorePos(SavedPos); |
| 1392 return NULL; | 1371 return; |
| 1393 } | 1372 } |
| 1394 FX_DWORD parser_gennum = FXSYS_atoi(word); | |
| 1395 if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) { | 1373 if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) { |
| 1396 m_Syntax.RestorePos(SavedPos); | 1374 m_Syntax.RestorePos(SavedPos); |
| 1397 return NULL; | 1375 return; |
| 1398 } | 1376 } |
| 1399 CPDF_Object* pObj = m_Syntax.GetObject(pObjList, objnum, parser_gennum, pCon
text); | 1377 void* pResult = |
| 1378 FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), |
| 1379 sizeof(FX_FILESIZE), _CompareFileSize); |
| 1380 if (pResult == NULL) { |
| 1381 m_Syntax.RestorePos(SavedPos); |
| 1382 return; |
| 1383 } |
| 1384 FX_FILESIZE nextoff = ((FX_FILESIZE*)pResult)[1]; |
| 1385 FX_BOOL bNextOffValid = FALSE; |
| 1386 if (nextoff != pos) { |
| 1387 m_Syntax.RestorePos(nextoff); |
| 1388 word = m_Syntax.GetNextWord(bIsNumber); |
| 1389 if (word == FX_BSTRC("xref")) { |
| 1390 bNextOffValid = TRUE; |
| 1391 } else if (bIsNumber) { |
| 1392 word = m_Syntax.GetNextWord(bIsNumber); |
| 1393 if (bIsNumber && m_Syntax.GetKeyword() == FX_BSTRC("obj")) { |
| 1394 bNextOffValid = TRUE; |
| 1395 } |
| 1396 } |
| 1397 } |
| 1398 if (!bNextOffValid) { |
| 1399 m_Syntax.RestorePos(pos); |
| 1400 while (1) { |
| 1401 if (m_Syntax.GetKeyword() == FX_BSTRC("endobj")) { |
| 1402 break; |
| 1403 } |
| 1404 if (m_Syntax.SavePos() == m_Syntax.m_FileLen) { |
| 1405 break; |
| 1406 } |
| 1407 } |
| 1408 nextoff = m_Syntax.SavePos(); |
| 1409 } |
| 1410 size = (FX_DWORD)(nextoff - pos); |
| 1411 pBuffer = FX_Alloc(uint8_t, size); |
| 1412 m_Syntax.RestorePos(pos); |
| 1413 m_Syntax.ReadBlock(pBuffer, size); |
| 1414 m_Syntax.RestorePos(SavedPos); |
| 1415 } |
| 1416 } |
| 1417 CPDF_Object* CPDF_Parser::ParseIndirectObjectAt(CPDF_IndirectObjects* pObjList, |
| 1418 FX_FILESIZE pos, |
| 1419 FX_DWORD objnum, |
| 1420 PARSE_CONTEXT* pContext) { |
| 1421 FX_FILESIZE SavedPos = m_Syntax.SavePos(); |
| 1422 m_Syntax.RestorePos(pos); |
| 1423 FX_BOOL bIsNumber; |
| 1424 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); |
| 1425 if (!bIsNumber) { |
| 1426 m_Syntax.RestorePos(SavedPos); |
| 1427 return NULL; |
| 1428 } |
| 1429 FX_FILESIZE objOffset = m_Syntax.SavePos(); |
| 1430 objOffset -= word.GetLength(); |
| 1431 FX_DWORD parser_objnum = FXSYS_atoi(word); |
| 1432 if (objnum && parser_objnum != objnum) { |
| 1433 m_Syntax.RestorePos(SavedPos); |
| 1434 return NULL; |
| 1435 } |
| 1436 word = m_Syntax.GetNextWord(bIsNumber); |
| 1437 if (!bIsNumber) { |
| 1438 m_Syntax.RestorePos(SavedPos); |
| 1439 return NULL; |
| 1440 } |
| 1441 FX_DWORD parser_gennum = FXSYS_atoi(word); |
| 1442 if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) { |
| 1443 m_Syntax.RestorePos(SavedPos); |
| 1444 return NULL; |
| 1445 } |
| 1446 CPDF_Object* pObj = |
| 1447 m_Syntax.GetObject(pObjList, objnum, parser_gennum, pContext); |
| 1448 m_Syntax.SavePos(); |
| 1449 CFX_ByteString bsWord = m_Syntax.GetKeyword(); |
| 1450 if (bsWord == FX_BSTRC("endobj")) { |
| 1400 m_Syntax.SavePos(); | 1451 m_Syntax.SavePos(); |
| 1401 CFX_ByteString bsWord = m_Syntax.GetKeyword(); | 1452 } |
| 1402 if (bsWord == FX_BSTRC("endobj")) { | 1453 m_Syntax.RestorePos(SavedPos); |
| 1403 m_Syntax.SavePos(); | 1454 if (pObj) { |
| 1404 } | 1455 if (!objnum) { |
| 1456 pObj->m_ObjNum = parser_objnum; |
| 1457 } |
| 1458 pObj->m_GenNum = parser_gennum; |
| 1459 } |
| 1460 return pObj; |
| 1461 } |
| 1462 CPDF_Object* CPDF_Parser::ParseIndirectObjectAtByStrict( |
| 1463 CPDF_IndirectObjects* pObjList, |
| 1464 FX_FILESIZE pos, |
| 1465 FX_DWORD objnum, |
| 1466 struct PARSE_CONTEXT* pContext, |
| 1467 FX_FILESIZE* pResultPos) { |
| 1468 FX_FILESIZE SavedPos = m_Syntax.SavePos(); |
| 1469 m_Syntax.RestorePos(pos); |
| 1470 FX_BOOL bIsNumber; |
| 1471 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); |
| 1472 if (!bIsNumber) { |
| 1405 m_Syntax.RestorePos(SavedPos); | 1473 m_Syntax.RestorePos(SavedPos); |
| 1474 return NULL; |
| 1475 } |
| 1476 FX_DWORD parser_objnum = FXSYS_atoi(word); |
| 1477 if (objnum && parser_objnum != objnum) { |
| 1478 m_Syntax.RestorePos(SavedPos); |
| 1479 return NULL; |
| 1480 } |
| 1481 word = m_Syntax.GetNextWord(bIsNumber); |
| 1482 if (!bIsNumber) { |
| 1483 m_Syntax.RestorePos(SavedPos); |
| 1484 return NULL; |
| 1485 } |
| 1486 FX_DWORD gennum = FXSYS_atoi(word); |
| 1487 if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) { |
| 1488 m_Syntax.RestorePos(SavedPos); |
| 1489 return NULL; |
| 1490 } |
| 1491 CPDF_Object* pObj = |
| 1492 m_Syntax.GetObjectByStrict(pObjList, objnum, gennum, pContext); |
| 1493 if (pResultPos) { |
| 1494 *pResultPos = m_Syntax.m_Pos; |
| 1495 } |
| 1496 m_Syntax.RestorePos(SavedPos); |
| 1497 return pObj; |
| 1498 } |
| 1499 CPDF_Dictionary* CPDF_Parser::LoadTrailerV4() { |
| 1500 if (m_Syntax.GetKeyword() != FX_BSTRC("trailer")) { |
| 1501 return NULL; |
| 1502 } |
| 1503 CPDF_Object* pObj = m_Syntax.GetObject(m_pDocument, 0, 0, 0); |
| 1504 if (pObj == NULL || pObj->GetType() != PDFOBJ_DICTIONARY) { |
| 1406 if (pObj) { | 1505 if (pObj) { |
| 1407 if (!objnum) { | 1506 pObj->Release(); |
| 1408 pObj->m_ObjNum = parser_objnum; | 1507 } |
| 1409 } | 1508 return NULL; |
| 1410 pObj->m_GenNum = parser_gennum; | 1509 } |
| 1411 } | 1510 return (CPDF_Dictionary*)pObj; |
| 1412 return pObj; | 1511 } |
| 1413 } | 1512 FX_DWORD CPDF_Parser::GetPermissions(FX_BOOL bCheckRevision) { |
| 1414 CPDF_Object* CPDF_Parser::ParseIndirectObjectAtByStrict(CPDF_IndirectObjects* pO
bjList, FX_FILESIZE pos, FX_DWORD objnum, | 1513 if (m_pSecurityHandler == NULL) { |
| 1415 struct PARSE_CONTEXT* pContext, FX_FILESIZE *pResultPos) | 1514 return (FX_DWORD)-1; |
| 1416 { | 1515 } |
| 1417 FX_FILESIZE SavedPos = m_Syntax.SavePos(); | 1516 FX_DWORD dwPermission = m_pSecurityHandler->GetPermissions(); |
| 1418 m_Syntax.RestorePos(pos); | 1517 if (m_pEncryptDict && |
| 1419 FX_BOOL bIsNumber; | 1518 m_pEncryptDict->GetString(FX_BSTRC("Filter")) == FX_BSTRC("Standard")) { |
| 1420 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); | 1519 dwPermission &= 0xFFFFFFFC; |
| 1421 if (!bIsNumber) { | 1520 dwPermission |= 0xFFFFF0C0; |
| 1422 m_Syntax.RestorePos(SavedPos); | 1521 if (bCheckRevision && m_pEncryptDict->GetInteger(FX_BSTRC("R")) == 2) { |
| 1423 return NULL; | 1522 dwPermission &= 0xFFFFF0FF; |
| 1424 } | 1523 } |
| 1425 FX_DWORD parser_objnum = FXSYS_atoi(word); | 1524 } |
| 1426 if (objnum && parser_objnum != objnum) { | 1525 return dwPermission; |
| 1427 m_Syntax.RestorePos(SavedPos); | 1526 } |
| 1428 return NULL; | 1527 FX_BOOL CPDF_Parser::IsOwner() { |
| 1429 } | 1528 return m_pSecurityHandler == NULL ? TRUE : m_pSecurityHandler->IsOwner(); |
| 1430 word = m_Syntax.GetNextWord(bIsNumber); | 1529 } |
| 1431 if (!bIsNumber) { | 1530 void CPDF_Parser::SetSecurityHandler(CPDF_SecurityHandler* pSecurityHandler, |
| 1432 m_Syntax.RestorePos(SavedPos); | 1531 FX_BOOL bForced) { |
| 1433 return NULL; | 1532 ASSERT(m_pSecurityHandler == NULL); |
| 1434 } | 1533 if (!m_bForceUseSecurityHandler) { |
| 1435 FX_DWORD gennum = FXSYS_atoi(word); | 1534 delete m_pSecurityHandler; |
| 1436 if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) { | 1535 m_pSecurityHandler = NULL; |
| 1437 m_Syntax.RestorePos(SavedPos); | 1536 } |
| 1438 return NULL; | 1537 m_bForceUseSecurityHandler = bForced; |
| 1439 } | 1538 m_pSecurityHandler = pSecurityHandler; |
| 1440 CPDF_Object* pObj = m_Syntax.GetObjectByStrict(pObjList, objnum, gennum, pCo
ntext); | 1539 if (m_bForceUseSecurityHandler) { |
| 1441 if (pResultPos) { | 1540 return; |
| 1442 *pResultPos = m_Syntax.m_Pos; | 1541 } |
| 1443 } | 1542 m_Syntax.m_pCryptoHandler = pSecurityHandler->CreateCryptoHandler(); |
| 1543 m_Syntax.m_pCryptoHandler->Init(NULL, pSecurityHandler); |
| 1544 } |
| 1545 FX_BOOL CPDF_Parser::IsLinearizedFile(IFX_FileRead* pFileAccess, |
| 1546 FX_DWORD offset) { |
| 1547 m_Syntax.InitParser(pFileAccess, offset); |
| 1548 m_Syntax.RestorePos(m_Syntax.m_HeaderOffset + 9); |
| 1549 FX_FILESIZE SavedPos = m_Syntax.SavePos(); |
| 1550 FX_BOOL bIsNumber; |
| 1551 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); |
| 1552 if (!bIsNumber) { |
| 1553 return FALSE; |
| 1554 } |
| 1555 FX_DWORD objnum = FXSYS_atoi(word); |
| 1556 word = m_Syntax.GetNextWord(bIsNumber); |
| 1557 if (!bIsNumber) { |
| 1558 return FALSE; |
| 1559 } |
| 1560 FX_DWORD gennum = FXSYS_atoi(word); |
| 1561 if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) { |
| 1444 m_Syntax.RestorePos(SavedPos); | 1562 m_Syntax.RestorePos(SavedPos); |
| 1445 return pObj; | 1563 return FALSE; |
| 1446 } | 1564 } |
| 1447 CPDF_Dictionary* CPDF_Parser::LoadTrailerV4() | 1565 m_pLinearized = m_Syntax.GetObject(NULL, objnum, gennum, 0); |
| 1448 { | 1566 if (!m_pLinearized) { |
| 1449 if (m_Syntax.GetKeyword() != FX_BSTRC("trailer")) { | 1567 return FALSE; |
| 1450 return NULL; | 1568 } |
| 1451 } | 1569 if (m_pLinearized->GetDict() && |
| 1452 CPDF_Object* pObj = m_Syntax.GetObject(m_pDocument, 0, 0, 0); | 1570 m_pLinearized->GetDict()->GetElement(FX_BSTRC("Linearized"))) { |
| 1453 if (pObj == NULL || pObj->GetType() != PDFOBJ_DICTIONARY) { | 1571 m_Syntax.GetNextWord(bIsNumber); |
| 1454 if (pObj) { | 1572 CPDF_Object* pLen = m_pLinearized->GetDict()->GetElement(FX_BSTRC("L")); |
| 1455 pObj->Release(); | 1573 if (!pLen) { |
| 1456 } | 1574 m_pLinearized->Release(); |
| 1457 return NULL; | 1575 m_pLinearized = NULL; |
| 1458 } | 1576 return FALSE; |
| 1459 return (CPDF_Dictionary*)pObj; | 1577 } |
| 1460 } | 1578 if (pLen->GetInteger() != (int)pFileAccess->GetSize()) { |
| 1461 FX_DWORD CPDF_Parser::GetPermissions(FX_BOOL bCheckRevision) | 1579 return FALSE; |
| 1462 { | 1580 } |
| 1463 if (m_pSecurityHandler == NULL) { | 1581 CPDF_Object* pNo = m_pLinearized->GetDict()->GetElement(FX_BSTRC("P")); |
| 1464 return (FX_DWORD) - 1; | 1582 if (pNo && pNo->GetType() == PDFOBJ_NUMBER) { |
| 1465 } | 1583 m_dwFirstPageNo = pNo->GetInteger(); |
| 1466 FX_DWORD dwPermission = m_pSecurityHandler->GetPermissions(); | 1584 } |
| 1467 if (m_pEncryptDict && m_pEncryptDict->GetString(FX_BSTRC("Filter")) == FX_BS
TRC("Standard")) { | 1585 CPDF_Object* pTable = m_pLinearized->GetDict()->GetElement(FX_BSTRC("T")); |
| 1468 dwPermission &= 0xFFFFFFFC; | 1586 if (pTable && pTable->GetType() == PDFOBJ_NUMBER) { |
| 1469 dwPermission |= 0xFFFFF0C0; | 1587 m_LastXRefOffset = pTable->GetInteger(); |
| 1470 if(bCheckRevision && m_pEncryptDict->GetInteger(FX_BSTRC("R")) == 2) { | 1588 } |
| 1471 dwPermission &= 0xFFFFF0FF; | 1589 return TRUE; |
| 1472 } | 1590 } |
| 1473 } | 1591 m_pLinearized->Release(); |
| 1474 return dwPermission; | 1592 m_pLinearized = NULL; |
| 1475 } | 1593 return FALSE; |
| 1476 FX_BOOL CPDF_Parser::IsOwner() | 1594 } |
| 1477 { | 1595 FX_DWORD CPDF_Parser::StartAsynParse(IFX_FileRead* pFileAccess, |
| 1478 return m_pSecurityHandler == NULL ? TRUE : m_pSecurityHandler->IsOwner(); | 1596 FX_BOOL bReParse, |
| 1479 } | 1597 FX_BOOL bOwnFileRead) { |
| 1480 void CPDF_Parser::SetSecurityHandler(CPDF_SecurityHandler* pSecurityHandler, FX_
BOOL bForced) | 1598 CloseParser(bReParse); |
| 1481 { | 1599 m_bXRefStream = FALSE; |
| 1482 ASSERT(m_pSecurityHandler == NULL); | 1600 m_LastXRefOffset = 0; |
| 1483 if (!m_bForceUseSecurityHandler) { | 1601 m_bOwnFileRead = bOwnFileRead; |
| 1484 delete m_pSecurityHandler; | 1602 int32_t offset = GetHeaderOffset(pFileAccess); |
| 1485 m_pSecurityHandler = NULL; | 1603 if (offset == -1) { |
| 1486 } | 1604 return PDFPARSE_ERROR_FORMAT; |
| 1487 m_bForceUseSecurityHandler = bForced; | 1605 } |
| 1488 m_pSecurityHandler = pSecurityHandler; | 1606 if (!IsLinearizedFile(pFileAccess, offset)) { |
| 1489 if (m_bForceUseSecurityHandler) { | 1607 m_Syntax.m_pFileAccess = NULL; |
| 1490 return; | 1608 return StartParse(pFileAccess, bReParse, bOwnFileRead); |
| 1491 } | 1609 } |
| 1492 m_Syntax.m_pCryptoHandler = pSecurityHandler->CreateCryptoHandler(); | 1610 if (!bReParse) { |
| 1493 m_Syntax.m_pCryptoHandler->Init(NULL, pSecurityHandler); | 1611 m_pDocument = new CPDF_Document(this); |
| 1494 } | 1612 } |
| 1495 FX_BOOL CPDF_Parser::IsLinearizedFile(IFX_FileRead* pFileAccess, FX_DWORD offset
) | 1613 FX_FILESIZE dwFirstXRefOffset = m_Syntax.SavePos(); |
| 1496 { | 1614 FX_BOOL bXRefRebuilt = FALSE; |
| 1497 m_Syntax.InitParser(pFileAccess, offset); | 1615 FX_BOOL bLoadV4 = FALSE; |
| 1498 m_Syntax.RestorePos(m_Syntax.m_HeaderOffset + 9); | 1616 if (!(bLoadV4 = LoadCrossRefV4(dwFirstXRefOffset, 0, FALSE, FALSE)) && |
| 1499 FX_FILESIZE SavedPos = m_Syntax.SavePos(); | 1617 !LoadCrossRefV5(dwFirstXRefOffset, dwFirstXRefOffset, TRUE)) { |
| 1500 FX_BOOL bIsNumber; | 1618 if (!RebuildCrossRef()) { |
| 1501 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); | 1619 return PDFPARSE_ERROR_FORMAT; |
| 1502 if (!bIsNumber) { | 1620 } |
| 1503 return FALSE; | 1621 bXRefRebuilt = TRUE; |
| 1504 } | |
| 1505 FX_DWORD objnum = FXSYS_atoi(word); | |
| 1506 word = m_Syntax.GetNextWord(bIsNumber); | |
| 1507 if (!bIsNumber) { | |
| 1508 return FALSE; | |
| 1509 } | |
| 1510 FX_DWORD gennum = FXSYS_atoi(word); | |
| 1511 if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) { | |
| 1512 m_Syntax.RestorePos(SavedPos); | |
| 1513 return FALSE; | |
| 1514 } | |
| 1515 m_pLinearized = m_Syntax.GetObject(NULL, objnum, gennum, 0); | |
| 1516 if (!m_pLinearized) { | |
| 1517 return FALSE; | |
| 1518 } | |
| 1519 if (m_pLinearized->GetDict() && m_pLinearized->GetDict()->GetElement(FX_BSTR
C("Linearized"))) { | |
| 1520 m_Syntax.GetNextWord(bIsNumber); | |
| 1521 CPDF_Object *pLen = m_pLinearized->GetDict()->GetElement(FX_BSTRC("L")); | |
| 1522 if (!pLen) { | |
| 1523 m_pLinearized->Release(); | |
| 1524 m_pLinearized = NULL; | |
| 1525 return FALSE; | |
| 1526 } | |
| 1527 if (pLen->GetInteger() != (int)pFileAccess->GetSize()) { | |
| 1528 return FALSE; | |
| 1529 } | |
| 1530 CPDF_Object *pNo = m_pLinearized->GetDict()->GetElement(FX_BSTRC("P")); | |
| 1531 if (pNo && pNo->GetType() == PDFOBJ_NUMBER) { | |
| 1532 m_dwFirstPageNo = pNo->GetInteger(); | |
| 1533 } | |
| 1534 CPDF_Object *pTable = m_pLinearized->GetDict()->GetElement(FX_BSTRC("T")
); | |
| 1535 if (pTable && pTable->GetType() == PDFOBJ_NUMBER) { | |
| 1536 m_LastXRefOffset = pTable->GetInteger(); | |
| 1537 } | |
| 1538 return TRUE; | |
| 1539 } | |
| 1540 m_pLinearized->Release(); | |
| 1541 m_pLinearized = NULL; | |
| 1542 return FALSE; | |
| 1543 } | |
| 1544 FX_DWORD CPDF_Parser::StartAsynParse(IFX_FileRead* pFileAccess, FX_BOOL bReParse
, FX_BOOL bOwnFileRead) | |
| 1545 { | |
| 1546 CloseParser(bReParse); | |
| 1547 m_bXRefStream = FALSE; | |
| 1548 m_LastXRefOffset = 0; | 1622 m_LastXRefOffset = 0; |
| 1549 m_bOwnFileRead = bOwnFileRead; | 1623 } |
| 1550 int32_t offset = GetHeaderOffset(pFileAccess); | 1624 if (bLoadV4) { |
| 1551 if (offset == -1) { | 1625 m_pTrailer = LoadTrailerV4(); |
| 1552 return PDFPARSE_ERROR_FORMAT; | 1626 if (m_pTrailer == NULL) { |
| 1553 } | 1627 return FALSE; |
| 1554 if (!IsLinearizedFile(pFileAccess, offset)) { | 1628 } |
| 1555 m_Syntax.m_pFileAccess = NULL; | 1629 int32_t xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size")); |
| 1556 return StartParse(pFileAccess, bReParse, bOwnFileRead); | 1630 if (xrefsize > 0) { |
| 1557 } | 1631 m_CrossRef.SetSize(xrefsize); |
| 1558 if (!bReParse) { | 1632 m_V5Type.SetSize(xrefsize); |
| 1559 m_pDocument = new CPDF_Document(this); | 1633 } |
| 1560 } | 1634 } |
| 1561 FX_FILESIZE dwFirstXRefOffset = m_Syntax.SavePos(); | 1635 FX_DWORD dwRet = SetEncryptHandler(); |
| 1562 FX_BOOL bXRefRebuilt = FALSE; | 1636 if (dwRet != PDFPARSE_ERROR_SUCCESS) { |
| 1563 FX_BOOL bLoadV4 = FALSE; | 1637 return dwRet; |
| 1564 if (!(bLoadV4 = LoadCrossRefV4(dwFirstXRefOffset, 0, FALSE, FALSE)) && !Load
CrossRefV5(dwFirstXRefOffset, dwFirstXRefOffset, TRUE)) { | 1638 } |
| 1565 if (!RebuildCrossRef()) { | 1639 m_pDocument->LoadAsynDoc(m_pLinearized->GetDict()); |
| 1566 return PDFPARSE_ERROR_FORMAT; | 1640 if (m_pDocument->GetRoot() == NULL || m_pDocument->GetPageCount() == 0) { |
| 1567 } | 1641 if (bXRefRebuilt) { |
| 1568 bXRefRebuilt = TRUE; | 1642 return PDFPARSE_ERROR_FORMAT; |
| 1569 m_LastXRefOffset = 0; | 1643 } |
| 1570 } | 1644 ReleaseEncryptHandler(); |
| 1571 if (bLoadV4) { | 1645 if (!RebuildCrossRef()) { |
| 1572 m_pTrailer = LoadTrailerV4(); | 1646 return PDFPARSE_ERROR_FORMAT; |
| 1573 if (m_pTrailer == NULL) { | 1647 } |
| 1574 return FALSE; | 1648 dwRet = SetEncryptHandler(); |
| 1575 } | |
| 1576 int32_t xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size")); | |
| 1577 if (xrefsize > 0) { | |
| 1578 m_CrossRef.SetSize(xrefsize); | |
| 1579 m_V5Type.SetSize(xrefsize); | |
| 1580 } | |
| 1581 } | |
| 1582 FX_DWORD dwRet = SetEncryptHandler(); | |
| 1583 if (dwRet != PDFPARSE_ERROR_SUCCESS) { | 1649 if (dwRet != PDFPARSE_ERROR_SUCCESS) { |
| 1584 return dwRet; | 1650 return dwRet; |
| 1585 } | 1651 } |
| 1586 m_pDocument->LoadAsynDoc(m_pLinearized->GetDict()); | 1652 m_pDocument->LoadAsynDoc(m_pLinearized->GetDict()); |
| 1587 if (m_pDocument->GetRoot() == NULL || m_pDocument->GetPageCount() == 0) { | 1653 if (m_pDocument->GetRoot() == NULL) { |
| 1588 if (bXRefRebuilt) { | 1654 return PDFPARSE_ERROR_FORMAT; |
| 1589 return PDFPARSE_ERROR_FORMAT; | 1655 } |
| 1590 } | 1656 } |
| 1591 ReleaseEncryptHandler(); | 1657 FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(), |
| 1592 if (!RebuildCrossRef()) { | 1658 sizeof(FX_FILESIZE), _CompareFileSize); |
| 1593 return PDFPARSE_ERROR_FORMAT; | 1659 FX_DWORD RootObjNum = GetRootObjNum(); |
| 1594 } | 1660 if (RootObjNum == 0) { |
| 1595 dwRet = SetEncryptHandler(); | 1661 ReleaseEncryptHandler(); |
| 1596 if (dwRet != PDFPARSE_ERROR_SUCCESS) { | 1662 RebuildCrossRef(); |
| 1597 return dwRet; | 1663 RootObjNum = GetRootObjNum(); |
| 1598 } | |
| 1599 m_pDocument->LoadAsynDoc(m_pLinearized->GetDict()); | |
| 1600 if (m_pDocument->GetRoot() == NULL) { | |
| 1601 return PDFPARSE_ERROR_FORMAT; | |
| 1602 } | |
| 1603 } | |
| 1604 FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FI
LESIZE), _CompareFileSize); | |
| 1605 FX_DWORD RootObjNum = GetRootObjNum(); | |
| 1606 if (RootObjNum == 0) { | 1664 if (RootObjNum == 0) { |
| 1607 ReleaseEncryptHandler(); | 1665 return PDFPARSE_ERROR_FORMAT; |
| 1608 RebuildCrossRef(); | 1666 } |
| 1609 RootObjNum = GetRootObjNum(); | 1667 dwRet = SetEncryptHandler(); |
| 1610 if (RootObjNum == 0) { | 1668 if (dwRet != PDFPARSE_ERROR_SUCCESS) { |
| 1611 return PDFPARSE_ERROR_FORMAT; | 1669 return dwRet; |
| 1612 } | 1670 } |
| 1613 dwRet = SetEncryptHandler(); | 1671 } |
| 1614 if (dwRet != PDFPARSE_ERROR_SUCCESS) { | 1672 if (m_pSecurityHandler && m_pSecurityHandler->IsMetadataEncrypted()) { |
| 1615 return dwRet; | 1673 CPDF_Object* pMetadata = |
| 1616 } | 1674 m_pDocument->GetRoot()->GetElement(FX_BSTRC("Metadata")); |
| 1617 } | 1675 if (pMetadata && pMetadata->GetType() == PDFOBJ_REFERENCE) { |
| 1618 if (m_pSecurityHandler && m_pSecurityHandler->IsMetadataEncrypted()) { | 1676 m_Syntax.m_MetadataObjnum = ((CPDF_Reference*)pMetadata)->GetRefObjNum(); |
| 1619 CPDF_Object* pMetadata = m_pDocument->GetRoot()->GetElement(FX_BSTRC("Me
tadata")); | 1677 } |
| 1620 if (pMetadata && pMetadata->GetType() == PDFOBJ_REFERENCE) { | 1678 } |
| 1621 m_Syntax.m_MetadataObjnum = ((CPDF_Reference*) pMetadata)->GetRefObj
Num(); | 1679 return PDFPARSE_ERROR_SUCCESS; |
| 1622 } | 1680 } |
| 1623 } | 1681 FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV5(FX_FILESIZE xrefpos) { |
| 1624 return PDFPARSE_ERROR_SUCCESS; | 1682 if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) { |
| 1625 } | 1683 return FALSE; |
| 1626 FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV5(FX_FILESIZE xrefpos) | 1684 } |
| 1627 { | 1685 while (xrefpos) |
| 1628 if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) { | 1686 if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) { |
| 1629 return FALSE; | 1687 return FALSE; |
| 1630 } | 1688 } |
| 1631 while (xrefpos) | 1689 m_ObjectStreamMap.InitHashTable(101, FALSE); |
| 1632 if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) { | 1690 m_bXRefStream = TRUE; |
| 1633 return FALSE; | 1691 return TRUE; |
| 1634 } | 1692 } |
| 1635 m_ObjectStreamMap.InitHashTable(101, FALSE); | 1693 FX_DWORD CPDF_Parser::LoadLinearizedMainXRefTable() { |
| 1636 m_bXRefStream = TRUE; | 1694 FX_DWORD dwSaveMetadataObjnum = m_Syntax.m_MetadataObjnum; |
| 1637 return TRUE; | 1695 m_Syntax.m_MetadataObjnum = 0; |
| 1638 } | 1696 if (m_pTrailer) { |
| 1639 FX_DWORD CPDF_Parser::LoadLinearizedMainXRefTable() | 1697 m_pTrailer->Release(); |
| 1640 { | 1698 m_pTrailer = NULL; |
| 1641 FX_DWORD dwSaveMetadataObjnum = m_Syntax.m_MetadataObjnum; | 1699 } |
| 1642 m_Syntax.m_MetadataObjnum = 0; | 1700 m_Syntax.RestorePos(m_LastXRefOffset - m_Syntax.m_HeaderOffset); |
| 1643 if (m_pTrailer) { | 1701 uint8_t ch = 0; |
| 1644 m_pTrailer->Release(); | 1702 FX_DWORD dwCount = 0; |
| 1645 m_pTrailer = NULL; | 1703 m_Syntax.GetNextChar(ch); |
| 1646 } | 1704 int32_t type = PDF_CharType[ch]; |
| 1647 m_Syntax.RestorePos(m_LastXRefOffset - m_Syntax.m_HeaderOffset); | 1705 while (type == 'W') { |
| 1648 uint8_t ch = 0; | 1706 ++dwCount; |
| 1649 FX_DWORD dwCount = 0; | 1707 if (m_Syntax.m_FileLen >= |
| 1708 (FX_FILESIZE)(m_Syntax.SavePos() + m_Syntax.m_HeaderOffset)) { |
| 1709 break; |
| 1710 } |
| 1650 m_Syntax.GetNextChar(ch); | 1711 m_Syntax.GetNextChar(ch); |
| 1651 int32_t type = PDF_CharType[ch]; | 1712 type = PDF_CharType[ch]; |
| 1652 while (type == 'W') { | 1713 } |
| 1653 ++dwCount; | 1714 m_LastXRefOffset += dwCount; |
| 1654 if (m_Syntax.m_FileLen >= (FX_FILESIZE)(m_Syntax.SavePos() + m_Syntax.m_
HeaderOffset)) { | 1715 FX_POSITION pos = m_ObjectStreamMap.GetStartPosition(); |
| 1655 break; | 1716 while (pos) { |
| 1656 } | 1717 void* objnum; |
| 1657 m_Syntax.GetNextChar(ch); | 1718 CPDF_StreamAcc* pStream; |
| 1658 type = PDF_CharType[ch]; | 1719 m_ObjectStreamMap.GetNextAssoc(pos, objnum, (void*&)pStream); |
| 1659 } | 1720 delete pStream; |
| 1660 m_LastXRefOffset += dwCount; | 1721 } |
| 1661 FX_POSITION pos = m_ObjectStreamMap.GetStartPosition(); | 1722 m_ObjectStreamMap.RemoveAll(); |
| 1662 while (pos) { | 1723 if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) && |
| 1663 void* objnum; | 1724 !LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) { |
| 1664 CPDF_StreamAcc* pStream; | 1725 m_LastXRefOffset = 0; |
| 1665 m_ObjectStreamMap.GetNextAssoc(pos, objnum, (void*&)pStream); | |
| 1666 delete pStream; | |
| 1667 } | |
| 1668 m_ObjectStreamMap.RemoveAll(); | |
| 1669 if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) && !
LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) { | |
| 1670 m_LastXRefOffset = 0; | |
| 1671 m_Syntax.m_MetadataObjnum = dwSaveMetadataObjnum; | |
| 1672 return PDFPARSE_ERROR_FORMAT; | |
| 1673 } | |
| 1674 FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FI
LESIZE), _CompareFileSize); | |
| 1675 m_Syntax.m_MetadataObjnum = dwSaveMetadataObjnum; | 1726 m_Syntax.m_MetadataObjnum = dwSaveMetadataObjnum; |
| 1676 return PDFPARSE_ERROR_SUCCESS; | 1727 return PDFPARSE_ERROR_FORMAT; |
| 1728 } |
| 1729 FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(), |
| 1730 sizeof(FX_FILESIZE), _CompareFileSize); |
| 1731 m_Syntax.m_MetadataObjnum = dwSaveMetadataObjnum; |
| 1732 return PDFPARSE_ERROR_SUCCESS; |
| 1677 } | 1733 } |
| 1678 | 1734 |
| 1679 // static | 1735 // static |
| 1680 int CPDF_SyntaxParser::s_CurrentRecursionDepth = 0; | 1736 int CPDF_SyntaxParser::s_CurrentRecursionDepth = 0; |
| 1681 | 1737 |
| 1682 CPDF_SyntaxParser::CPDF_SyntaxParser() | 1738 CPDF_SyntaxParser::CPDF_SyntaxParser() { |
| 1683 { | 1739 m_pFileAccess = NULL; |
| 1684 m_pFileAccess = NULL; | 1740 m_pCryptoHandler = NULL; |
| 1685 m_pCryptoHandler = NULL; | 1741 m_pFileBuf = NULL; |
| 1742 m_BufSize = CPDF_ModuleMgr::kFileBufSize; |
| 1743 m_pFileBuf = NULL; |
| 1744 m_MetadataObjnum = 0; |
| 1745 m_dwWordPos = 0; |
| 1746 m_bFileStream = FALSE; |
| 1747 } |
| 1748 CPDF_SyntaxParser::~CPDF_SyntaxParser() { |
| 1749 if (m_pFileBuf) { |
| 1750 FX_Free(m_pFileBuf); |
| 1751 } |
| 1752 } |
| 1753 FX_BOOL CPDF_SyntaxParser::GetCharAt(FX_FILESIZE pos, uint8_t& ch) { |
| 1754 FX_FILESIZE save_pos = m_Pos; |
| 1755 m_Pos = pos; |
| 1756 FX_BOOL ret = GetNextChar(ch); |
| 1757 m_Pos = save_pos; |
| 1758 return ret; |
| 1759 } |
| 1760 FX_BOOL CPDF_SyntaxParser::GetNextChar(uint8_t& ch) { |
| 1761 FX_FILESIZE pos = m_Pos + m_HeaderOffset; |
| 1762 if (pos >= m_FileLen) { |
| 1763 return FALSE; |
| 1764 } |
| 1765 if (m_BufOffset >= pos || (FX_FILESIZE)(m_BufOffset + m_BufSize) <= pos) { |
| 1766 FX_FILESIZE read_pos = pos; |
| 1767 FX_DWORD read_size = m_BufSize; |
| 1768 if ((FX_FILESIZE)read_size > m_FileLen) { |
| 1769 read_size = (FX_DWORD)m_FileLen; |
| 1770 } |
| 1771 if ((FX_FILESIZE)(read_pos + read_size) > m_FileLen) { |
| 1772 if (m_FileLen < (FX_FILESIZE)read_size) { |
| 1773 read_pos = 0; |
| 1774 read_size = (FX_DWORD)m_FileLen; |
| 1775 } else { |
| 1776 read_pos = m_FileLen - read_size; |
| 1777 } |
| 1778 } |
| 1779 if (!m_pFileAccess->ReadBlock(m_pFileBuf, read_pos, read_size)) { |
| 1780 return FALSE; |
| 1781 } |
| 1782 m_BufOffset = read_pos; |
| 1783 } |
| 1784 ch = m_pFileBuf[pos - m_BufOffset]; |
| 1785 m_Pos++; |
| 1786 return TRUE; |
| 1787 } |
| 1788 FX_BOOL CPDF_SyntaxParser::GetCharAtBackward(FX_FILESIZE pos, uint8_t& ch) { |
| 1789 pos += m_HeaderOffset; |
| 1790 if (pos >= m_FileLen) { |
| 1791 return FALSE; |
| 1792 } |
| 1793 if (m_BufOffset >= pos || (FX_FILESIZE)(m_BufOffset + m_BufSize) <= pos) { |
| 1794 FX_FILESIZE read_pos; |
| 1795 if (pos < (FX_FILESIZE)m_BufSize) { |
| 1796 read_pos = 0; |
| 1797 } else { |
| 1798 read_pos = pos - m_BufSize + 1; |
| 1799 } |
| 1800 FX_DWORD read_size = m_BufSize; |
| 1801 if ((FX_FILESIZE)(read_pos + read_size) > m_FileLen) { |
| 1802 if (m_FileLen < (FX_FILESIZE)read_size) { |
| 1803 read_pos = 0; |
| 1804 read_size = (FX_DWORD)m_FileLen; |
| 1805 } else { |
| 1806 read_pos = m_FileLen - read_size; |
| 1807 } |
| 1808 } |
| 1809 if (!m_pFileAccess->ReadBlock(m_pFileBuf, read_pos, read_size)) { |
| 1810 return FALSE; |
| 1811 } |
| 1812 m_BufOffset = read_pos; |
| 1813 } |
| 1814 ch = m_pFileBuf[pos - m_BufOffset]; |
| 1815 return TRUE; |
| 1816 } |
| 1817 FX_BOOL CPDF_SyntaxParser::ReadBlock(uint8_t* pBuf, FX_DWORD size) { |
| 1818 if (!m_pFileAccess->ReadBlock(pBuf, m_Pos + m_HeaderOffset, size)) { |
| 1819 return FALSE; |
| 1820 } |
| 1821 m_Pos += size; |
| 1822 return TRUE; |
| 1823 } |
| 1824 #define MAX_WORD_BUFFER 256 |
| 1825 void CPDF_SyntaxParser::GetNextWord() { |
| 1826 m_WordSize = 0; |
| 1827 m_bIsNumber = TRUE; |
| 1828 uint8_t ch; |
| 1829 if (!GetNextChar(ch)) { |
| 1830 return; |
| 1831 } |
| 1832 uint8_t type = PDF_CharType[ch]; |
| 1833 while (1) { |
| 1834 while (type == 'W') { |
| 1835 if (!GetNextChar(ch)) { |
| 1836 return; |
| 1837 } |
| 1838 type = PDF_CharType[ch]; |
| 1839 } |
| 1840 if (ch != '%') { |
| 1841 break; |
| 1842 } |
| 1843 while (1) { |
| 1844 if (!GetNextChar(ch)) { |
| 1845 return; |
| 1846 } |
| 1847 if (ch == '\r' || ch == '\n') { |
| 1848 break; |
| 1849 } |
| 1850 } |
| 1851 type = PDF_CharType[ch]; |
| 1852 } |
| 1853 if (type == 'D') { |
| 1854 m_bIsNumber = FALSE; |
| 1855 m_WordBuffer[m_WordSize++] = ch; |
| 1856 if (ch == '/') { |
| 1857 while (1) { |
| 1858 if (!GetNextChar(ch)) { |
| 1859 return; |
| 1860 } |
| 1861 type = PDF_CharType[ch]; |
| 1862 if (type != 'R' && type != 'N') { |
| 1863 m_Pos--; |
| 1864 return; |
| 1865 } |
| 1866 if (m_WordSize < MAX_WORD_BUFFER) { |
| 1867 m_WordBuffer[m_WordSize++] = ch; |
| 1868 } |
| 1869 } |
| 1870 } else if (ch == '<') { |
| 1871 if (!GetNextChar(ch)) { |
| 1872 return; |
| 1873 } |
| 1874 if (ch == '<') { |
| 1875 m_WordBuffer[m_WordSize++] = ch; |
| 1876 } else { |
| 1877 m_Pos--; |
| 1878 } |
| 1879 } else if (ch == '>') { |
| 1880 if (!GetNextChar(ch)) { |
| 1881 return; |
| 1882 } |
| 1883 if (ch == '>') { |
| 1884 m_WordBuffer[m_WordSize++] = ch; |
| 1885 } else { |
| 1886 m_Pos--; |
| 1887 } |
| 1888 } |
| 1889 return; |
| 1890 } |
| 1891 while (1) { |
| 1892 if (m_WordSize < MAX_WORD_BUFFER) { |
| 1893 m_WordBuffer[m_WordSize++] = ch; |
| 1894 } |
| 1895 if (type != 'N') { |
| 1896 m_bIsNumber = FALSE; |
| 1897 } |
| 1898 if (!GetNextChar(ch)) { |
| 1899 return; |
| 1900 } |
| 1901 type = PDF_CharType[ch]; |
| 1902 if (type == 'D' || type == 'W') { |
| 1903 m_Pos--; |
| 1904 break; |
| 1905 } |
| 1906 } |
| 1907 } |
| 1908 CFX_ByteString CPDF_SyntaxParser::ReadString() { |
| 1909 uint8_t ch; |
| 1910 if (!GetNextChar(ch)) { |
| 1911 return CFX_ByteString(); |
| 1912 } |
| 1913 CFX_ByteTextBuf buf; |
| 1914 int32_t parlevel = 0; |
| 1915 int32_t status = 0, iEscCode = 0; |
| 1916 while (1) { |
| 1917 switch (status) { |
| 1918 case 0: |
| 1919 if (ch == ')') { |
| 1920 if (parlevel == 0) { |
| 1921 return buf.GetByteString(); |
| 1922 } |
| 1923 parlevel--; |
| 1924 buf.AppendChar(')'); |
| 1925 } else if (ch == '(') { |
| 1926 parlevel++; |
| 1927 buf.AppendChar('('); |
| 1928 } else if (ch == '\\') { |
| 1929 status = 1; |
| 1930 } else { |
| 1931 buf.AppendChar(ch); |
| 1932 } |
| 1933 break; |
| 1934 case 1: |
| 1935 if (ch >= '0' && ch <= '7') { |
| 1936 iEscCode = ch - '0'; |
| 1937 status = 2; |
| 1938 break; |
| 1939 } |
| 1940 if (ch == 'n') { |
| 1941 buf.AppendChar('\n'); |
| 1942 } else if (ch == 'r') { |
| 1943 buf.AppendChar('\r'); |
| 1944 } else if (ch == 't') { |
| 1945 buf.AppendChar('\t'); |
| 1946 } else if (ch == 'b') { |
| 1947 buf.AppendChar('\b'); |
| 1948 } else if (ch == 'f') { |
| 1949 buf.AppendChar('\f'); |
| 1950 } else if (ch == '\r') { |
| 1951 status = 4; |
| 1952 break; |
| 1953 } else if (ch == '\n') { |
| 1954 } else { |
| 1955 buf.AppendChar(ch); |
| 1956 } |
| 1957 status = 0; |
| 1958 break; |
| 1959 case 2: |
| 1960 if (ch >= '0' && ch <= '7') { |
| 1961 iEscCode = iEscCode * 8 + ch - '0'; |
| 1962 status = 3; |
| 1963 } else { |
| 1964 buf.AppendChar(iEscCode); |
| 1965 status = 0; |
| 1966 continue; |
| 1967 } |
| 1968 break; |
| 1969 case 3: |
| 1970 if (ch >= '0' && ch <= '7') { |
| 1971 iEscCode = iEscCode * 8 + ch - '0'; |
| 1972 buf.AppendChar(iEscCode); |
| 1973 status = 0; |
| 1974 } else { |
| 1975 buf.AppendChar(iEscCode); |
| 1976 status = 0; |
| 1977 continue; |
| 1978 } |
| 1979 break; |
| 1980 case 4: |
| 1981 status = 0; |
| 1982 if (ch != '\n') { |
| 1983 continue; |
| 1984 } |
| 1985 break; |
| 1986 } |
| 1987 if (!GetNextChar(ch)) { |
| 1988 break; |
| 1989 } |
| 1990 } |
| 1991 GetNextChar(ch); |
| 1992 return buf.GetByteString(); |
| 1993 } |
| 1994 CFX_ByteString CPDF_SyntaxParser::ReadHexString() { |
| 1995 uint8_t ch; |
| 1996 if (!GetNextChar(ch)) { |
| 1997 return CFX_ByteString(); |
| 1998 } |
| 1999 CFX_BinaryBuf buf; |
| 2000 FX_BOOL bFirst = TRUE; |
| 2001 uint8_t code = 0; |
| 2002 while (1) { |
| 2003 if (ch == '>') { |
| 2004 break; |
| 2005 } |
| 2006 if (ch >= '0' && ch <= '9') { |
| 2007 if (bFirst) { |
| 2008 code = (ch - '0') * 16; |
| 2009 } else { |
| 2010 code += ch - '0'; |
| 2011 buf.AppendByte((uint8_t)code); |
| 2012 } |
| 2013 bFirst = !bFirst; |
| 2014 } else if (ch >= 'A' && ch <= 'F') { |
| 2015 if (bFirst) { |
| 2016 code = (ch - 'A' + 10) * 16; |
| 2017 } else { |
| 2018 code += ch - 'A' + 10; |
| 2019 buf.AppendByte((uint8_t)code); |
| 2020 } |
| 2021 bFirst = !bFirst; |
| 2022 } else if (ch >= 'a' && ch <= 'f') { |
| 2023 if (bFirst) { |
| 2024 code = (ch - 'a' + 10) * 16; |
| 2025 } else { |
| 2026 code += ch - 'a' + 10; |
| 2027 buf.AppendByte((uint8_t)code); |
| 2028 } |
| 2029 bFirst = !bFirst; |
| 2030 } |
| 2031 if (!GetNextChar(ch)) { |
| 2032 break; |
| 2033 } |
| 2034 } |
| 2035 if (!bFirst) { |
| 2036 buf.AppendByte((uint8_t)code); |
| 2037 } |
| 2038 return buf.GetByteString(); |
| 2039 } |
| 2040 void CPDF_SyntaxParser::ToNextLine() { |
| 2041 uint8_t ch; |
| 2042 while (GetNextChar(ch)) { |
| 2043 if (ch == '\n') { |
| 2044 break; |
| 2045 } |
| 2046 if (ch == '\r') { |
| 2047 GetNextChar(ch); |
| 2048 if (ch != '\n') { |
| 2049 --m_Pos; |
| 2050 } |
| 2051 break; |
| 2052 } |
| 2053 } |
| 2054 } |
| 2055 void CPDF_SyntaxParser::ToNextWord() { |
| 2056 uint8_t ch; |
| 2057 if (!GetNextChar(ch)) { |
| 2058 return; |
| 2059 } |
| 2060 uint8_t type = PDF_CharType[ch]; |
| 2061 while (1) { |
| 2062 while (type == 'W') { |
| 2063 m_dwWordPos = m_Pos; |
| 2064 if (!GetNextChar(ch)) { |
| 2065 return; |
| 2066 } |
| 2067 type = PDF_CharType[ch]; |
| 2068 } |
| 2069 if (ch != '%') { |
| 2070 break; |
| 2071 } |
| 2072 while (1) { |
| 2073 if (!GetNextChar(ch)) { |
| 2074 return; |
| 2075 } |
| 2076 if (ch == '\r' || ch == '\n') { |
| 2077 break; |
| 2078 } |
| 2079 } |
| 2080 type = PDF_CharType[ch]; |
| 2081 } |
| 2082 m_Pos--; |
| 2083 } |
| 2084 CFX_ByteString CPDF_SyntaxParser::GetNextWord(FX_BOOL& bIsNumber) { |
| 2085 GetNextWord(); |
| 2086 bIsNumber = m_bIsNumber; |
| 2087 return CFX_ByteString((const FX_CHAR*)m_WordBuffer, m_WordSize); |
| 2088 } |
| 2089 CFX_ByteString CPDF_SyntaxParser::GetKeyword() { |
| 2090 GetNextWord(); |
| 2091 return CFX_ByteString((const FX_CHAR*)m_WordBuffer, m_WordSize); |
| 2092 } |
| 2093 CPDF_Object* CPDF_SyntaxParser::GetObject(CPDF_IndirectObjects* pObjList, |
| 2094 FX_DWORD objnum, |
| 2095 FX_DWORD gennum, |
| 2096 PARSE_CONTEXT* pContext, |
| 2097 FX_BOOL bDecrypt) { |
| 2098 CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth); |
| 2099 if (++s_CurrentRecursionDepth > kParserMaxRecursionDepth) { |
| 2100 return NULL; |
| 2101 } |
| 2102 FX_FILESIZE SavedPos = m_Pos; |
| 2103 FX_BOOL bTypeOnly = pContext && (pContext->m_Flags & PDFPARSE_TYPEONLY); |
| 2104 FX_BOOL bIsNumber; |
| 2105 CFX_ByteString word = GetNextWord(bIsNumber); |
| 2106 if (word.GetLength() == 0) { |
| 2107 if (bTypeOnly) { |
| 2108 return (CPDF_Object*)PDFOBJ_INVALID; |
| 2109 } |
| 2110 return NULL; |
| 2111 } |
| 2112 if (bIsNumber) { |
| 2113 FX_FILESIZE SavedPos = m_Pos; |
| 2114 CFX_ByteString nextword = GetNextWord(bIsNumber); |
| 2115 if (bIsNumber) { |
| 2116 CFX_ByteString nextword2 = GetNextWord(bIsNumber); |
| 2117 if (nextword2 == FX_BSTRC("R")) { |
| 2118 FX_DWORD objnum = FXSYS_atoi(word); |
| 2119 if (bTypeOnly) { |
| 2120 return (CPDF_Object*)PDFOBJ_REFERENCE; |
| 2121 } |
| 2122 return new CPDF_Reference(pObjList, objnum); |
| 2123 } |
| 2124 } |
| 2125 m_Pos = SavedPos; |
| 2126 if (bTypeOnly) { |
| 2127 return (CPDF_Object*)PDFOBJ_NUMBER; |
| 2128 } |
| 2129 return CPDF_Number::Create(word); |
| 2130 } |
| 2131 if (word == FX_BSTRC("true") || word == FX_BSTRC("false")) { |
| 2132 if (bTypeOnly) { |
| 2133 return (CPDF_Object*)PDFOBJ_BOOLEAN; |
| 2134 } |
| 2135 return CPDF_Boolean::Create(word == FX_BSTRC("true")); |
| 2136 } |
| 2137 if (word == FX_BSTRC("null")) { |
| 2138 if (bTypeOnly) { |
| 2139 return (CPDF_Object*)PDFOBJ_NULL; |
| 2140 } |
| 2141 return CPDF_Null::Create(); |
| 2142 } |
| 2143 if (word == FX_BSTRC("(")) { |
| 2144 if (bTypeOnly) { |
| 2145 return (CPDF_Object*)PDFOBJ_STRING; |
| 2146 } |
| 2147 CFX_ByteString str = ReadString(); |
| 2148 if (m_pCryptoHandler && bDecrypt) { |
| 2149 m_pCryptoHandler->Decrypt(objnum, gennum, str); |
| 2150 } |
| 2151 return CPDF_String::Create(str, FALSE); |
| 2152 } |
| 2153 if (word == FX_BSTRC("<")) { |
| 2154 if (bTypeOnly) { |
| 2155 return (CPDF_Object*)PDFOBJ_STRING; |
| 2156 } |
| 2157 CFX_ByteString str = ReadHexString(); |
| 2158 if (m_pCryptoHandler && bDecrypt) { |
| 2159 m_pCryptoHandler->Decrypt(objnum, gennum, str); |
| 2160 } |
| 2161 return CPDF_String::Create(str, TRUE); |
| 2162 } |
| 2163 if (word == FX_BSTRC("[")) { |
| 2164 if (bTypeOnly) { |
| 2165 return (CPDF_Object*)PDFOBJ_ARRAY; |
| 2166 } |
| 2167 CPDF_Array* pArray = CPDF_Array::Create(); |
| 2168 while (1) { |
| 2169 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum); |
| 2170 if (pObj == NULL) { |
| 2171 return pArray; |
| 2172 } |
| 2173 pArray->Add(pObj); |
| 2174 } |
| 2175 } |
| 2176 if (word[0] == '/') { |
| 2177 if (bTypeOnly) { |
| 2178 return (CPDF_Object*)PDFOBJ_NAME; |
| 2179 } |
| 2180 return CPDF_Name::Create( |
| 2181 PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))); |
| 2182 } |
| 2183 if (word == FX_BSTRC("<<")) { |
| 2184 if (bTypeOnly) { |
| 2185 return (CPDF_Object*)PDFOBJ_DICTIONARY; |
| 2186 } |
| 2187 if (pContext) { |
| 2188 pContext->m_DictStart = SavedPos; |
| 2189 } |
| 2190 CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); |
| 2191 int32_t nKeys = 0; |
| 2192 FX_FILESIZE dwSignValuePos = 0; |
| 2193 while (1) { |
| 2194 FX_BOOL bIsNumber; |
| 2195 CFX_ByteString key = GetNextWord(bIsNumber); |
| 2196 if (key.IsEmpty()) { |
| 2197 if (pDict) |
| 2198 pDict->Release(); |
| 2199 return NULL; |
| 2200 } |
| 2201 FX_FILESIZE SavedPos = m_Pos - key.GetLength(); |
| 2202 if (key == FX_BSTRC(">>")) { |
| 2203 break; |
| 2204 } |
| 2205 if (key == FX_BSTRC("endobj")) { |
| 2206 m_Pos = SavedPos; |
| 2207 break; |
| 2208 } |
| 2209 if (key[0] != '/') { |
| 2210 continue; |
| 2211 } |
| 2212 nKeys++; |
| 2213 key = PDF_NameDecode(key); |
| 2214 if (key == FX_BSTRC("/Contents")) { |
| 2215 dwSignValuePos = m_Pos; |
| 2216 } |
| 2217 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum); |
| 2218 if (pObj == NULL) { |
| 2219 continue; |
| 2220 } |
| 2221 if (key.GetLength() >= 1) { |
| 2222 if (nKeys < 32) { |
| 2223 pDict->SetAt(CFX_ByteStringC(key.c_str() + 1, key.GetLength() - 1), |
| 2224 pObj); |
| 2225 } else { |
| 2226 pDict->AddValue(CFX_ByteStringC(key.c_str() + 1, key.GetLength() - 1), |
| 2227 pObj); |
| 2228 } |
| 2229 } |
| 2230 } |
| 2231 if (IsSignatureDict(pDict)) { |
| 2232 FX_FILESIZE dwSavePos = m_Pos; |
| 2233 m_Pos = dwSignValuePos; |
| 2234 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, NULL, FALSE); |
| 2235 pDict->SetAt(FX_BSTRC("Contents"), pObj); |
| 2236 m_Pos = dwSavePos; |
| 2237 } |
| 2238 if (pContext) { |
| 2239 pContext->m_DictEnd = m_Pos; |
| 2240 if (pContext->m_Flags & PDFPARSE_NOSTREAM) { |
| 2241 return pDict; |
| 2242 } |
| 2243 } |
| 2244 FX_FILESIZE SavedPos = m_Pos; |
| 2245 FX_BOOL bIsNumber; |
| 2246 CFX_ByteString nextword = GetNextWord(bIsNumber); |
| 2247 if (nextword == FX_BSTRC("stream")) { |
| 2248 CPDF_Stream* pStream = ReadStream(pDict, pContext, objnum, gennum); |
| 2249 if (pStream) { |
| 2250 return pStream; |
| 2251 } |
| 2252 if (pDict) |
| 2253 pDict->Release(); |
| 2254 return NULL; |
| 2255 } else { |
| 2256 m_Pos = SavedPos; |
| 2257 return pDict; |
| 2258 } |
| 2259 } |
| 2260 if (word == FX_BSTRC(">>")) { |
| 2261 m_Pos = SavedPos; |
| 2262 return NULL; |
| 2263 } |
| 2264 if (bTypeOnly) { |
| 2265 return (CPDF_Object*)PDFOBJ_INVALID; |
| 2266 } |
| 2267 return NULL; |
| 2268 } |
| 2269 CPDF_Object* CPDF_SyntaxParser::GetObjectByStrict( |
| 2270 CPDF_IndirectObjects* pObjList, |
| 2271 FX_DWORD objnum, |
| 2272 FX_DWORD gennum, |
| 2273 struct PARSE_CONTEXT* pContext) { |
| 2274 CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth); |
| 2275 if (++s_CurrentRecursionDepth > kParserMaxRecursionDepth) { |
| 2276 return NULL; |
| 2277 } |
| 2278 FX_FILESIZE SavedPos = m_Pos; |
| 2279 FX_BOOL bTypeOnly = pContext && (pContext->m_Flags & PDFPARSE_TYPEONLY); |
| 2280 FX_BOOL bIsNumber; |
| 2281 CFX_ByteString word = GetNextWord(bIsNumber); |
| 2282 if (word.GetLength() == 0) { |
| 2283 if (bTypeOnly) { |
| 2284 return (CPDF_Object*)PDFOBJ_INVALID; |
| 2285 } |
| 2286 return NULL; |
| 2287 } |
| 2288 if (bIsNumber) { |
| 2289 FX_FILESIZE SavedPos = m_Pos; |
| 2290 CFX_ByteString nextword = GetNextWord(bIsNumber); |
| 2291 if (bIsNumber) { |
| 2292 CFX_ByteString nextword2 = GetNextWord(bIsNumber); |
| 2293 if (nextword2 == FX_BSTRC("R")) { |
| 2294 if (bTypeOnly) { |
| 2295 return (CPDF_Object*)PDFOBJ_REFERENCE; |
| 2296 } |
| 2297 FX_DWORD objnum = FXSYS_atoi(word); |
| 2298 return new CPDF_Reference(pObjList, objnum); |
| 2299 } |
| 2300 } |
| 2301 m_Pos = SavedPos; |
| 2302 if (bTypeOnly) { |
| 2303 return (CPDF_Object*)PDFOBJ_NUMBER; |
| 2304 } |
| 2305 return CPDF_Number::Create(word); |
| 2306 } |
| 2307 if (word == FX_BSTRC("true") || word == FX_BSTRC("false")) { |
| 2308 if (bTypeOnly) { |
| 2309 return (CPDF_Object*)PDFOBJ_BOOLEAN; |
| 2310 } |
| 2311 return CPDF_Boolean::Create(word == FX_BSTRC("true")); |
| 2312 } |
| 2313 if (word == FX_BSTRC("null")) { |
| 2314 if (bTypeOnly) { |
| 2315 return (CPDF_Object*)PDFOBJ_NULL; |
| 2316 } |
| 2317 return CPDF_Null::Create(); |
| 2318 } |
| 2319 if (word == FX_BSTRC("(")) { |
| 2320 if (bTypeOnly) { |
| 2321 return (CPDF_Object*)PDFOBJ_STRING; |
| 2322 } |
| 2323 CFX_ByteString str = ReadString(); |
| 2324 if (m_pCryptoHandler) { |
| 2325 m_pCryptoHandler->Decrypt(objnum, gennum, str); |
| 2326 } |
| 2327 return CPDF_String::Create(str, FALSE); |
| 2328 } |
| 2329 if (word == FX_BSTRC("<")) { |
| 2330 if (bTypeOnly) { |
| 2331 return (CPDF_Object*)PDFOBJ_STRING; |
| 2332 } |
| 2333 CFX_ByteString str = ReadHexString(); |
| 2334 if (m_pCryptoHandler) { |
| 2335 m_pCryptoHandler->Decrypt(objnum, gennum, str); |
| 2336 } |
| 2337 return CPDF_String::Create(str, TRUE); |
| 2338 } |
| 2339 if (word == FX_BSTRC("[")) { |
| 2340 if (bTypeOnly) { |
| 2341 return (CPDF_Object*)PDFOBJ_ARRAY; |
| 2342 } |
| 2343 CPDF_Array* pArray = CPDF_Array::Create(); |
| 2344 while (1) { |
| 2345 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum); |
| 2346 if (pObj == NULL) { |
| 2347 if (m_WordBuffer[0] == ']') { |
| 2348 return pArray; |
| 2349 } |
| 2350 if (pArray) { |
| 2351 pArray->Release(); |
| 2352 } |
| 2353 return NULL; |
| 2354 } |
| 2355 pArray->Add(pObj); |
| 2356 } |
| 2357 } |
| 2358 if (word[0] == '/') { |
| 2359 if (bTypeOnly) { |
| 2360 return (CPDF_Object*)PDFOBJ_NAME; |
| 2361 } |
| 2362 return CPDF_Name::Create( |
| 2363 PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))); |
| 2364 } |
| 2365 if (word == FX_BSTRC("<<")) { |
| 2366 if (bTypeOnly) { |
| 2367 return (CPDF_Object*)PDFOBJ_DICTIONARY; |
| 2368 } |
| 2369 if (pContext) { |
| 2370 pContext->m_DictStart = SavedPos; |
| 2371 } |
| 2372 CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); |
| 2373 while (1) { |
| 2374 FX_BOOL bIsNumber; |
| 2375 FX_FILESIZE SavedPos = m_Pos; |
| 2376 CFX_ByteString key = GetNextWord(bIsNumber); |
| 2377 if (key.IsEmpty()) { |
| 2378 if (pDict) { |
| 2379 pDict->Release(); |
| 2380 } |
| 2381 return NULL; |
| 2382 } |
| 2383 if (key == FX_BSTRC(">>")) { |
| 2384 break; |
| 2385 } |
| 2386 if (key == FX_BSTRC("endobj")) { |
| 2387 m_Pos = SavedPos; |
| 2388 break; |
| 2389 } |
| 2390 if (key[0] != '/') { |
| 2391 continue; |
| 2392 } |
| 2393 key = PDF_NameDecode(key); |
| 2394 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum); |
| 2395 if (pObj == NULL) { |
| 2396 if (pDict) { |
| 2397 pDict->Release(); |
| 2398 } |
| 2399 uint8_t ch; |
| 2400 while (1) { |
| 2401 if (!GetNextChar(ch)) { |
| 2402 break; |
| 2403 } |
| 2404 if (ch == 0x0A || ch == 0x0D) { |
| 2405 break; |
| 2406 } |
| 2407 } |
| 2408 return NULL; |
| 2409 } |
| 2410 if (key.GetLength() > 1) { |
| 2411 pDict->AddValue(CFX_ByteStringC(key.c_str() + 1, key.GetLength() - 1), |
| 2412 pObj); |
| 2413 } |
| 2414 } |
| 2415 if (pContext) { |
| 2416 pContext->m_DictEnd = m_Pos; |
| 2417 if (pContext->m_Flags & PDFPARSE_NOSTREAM) { |
| 2418 return pDict; |
| 2419 } |
| 2420 } |
| 2421 FX_FILESIZE SavedPos = m_Pos; |
| 2422 FX_BOOL bIsNumber; |
| 2423 CFX_ByteString nextword = GetNextWord(bIsNumber); |
| 2424 if (nextword == FX_BSTRC("stream")) { |
| 2425 CPDF_Stream* pStream = ReadStream(pDict, pContext, objnum, gennum); |
| 2426 if (pStream) { |
| 2427 return pStream; |
| 2428 } |
| 2429 if (pDict) { |
| 2430 pDict->Release(); |
| 2431 } |
| 2432 return NULL; |
| 2433 } else { |
| 2434 m_Pos = SavedPos; |
| 2435 return pDict; |
| 2436 } |
| 2437 } |
| 2438 if (word == FX_BSTRC(">>")) { |
| 2439 m_Pos = SavedPos; |
| 2440 return NULL; |
| 2441 } |
| 2442 if (bTypeOnly) { |
| 2443 return (CPDF_Object*)PDFOBJ_INVALID; |
| 2444 } |
| 2445 return NULL; |
| 2446 } |
| 2447 CPDF_Stream* CPDF_SyntaxParser::ReadStream(CPDF_Dictionary* pDict, |
| 2448 PARSE_CONTEXT* pContext, |
| 2449 FX_DWORD objnum, |
| 2450 FX_DWORD gennum) { |
| 2451 CPDF_Object* pLenObj = pDict->GetElement(FX_BSTRC("Length")); |
| 2452 FX_FILESIZE len = 0; |
| 2453 if (pLenObj && ((pLenObj->GetType() != PDFOBJ_REFERENCE) || |
| 2454 ((((CPDF_Reference*)pLenObj)->GetObjList() != NULL) && |
| 2455 ((CPDF_Reference*)pLenObj)->GetRefObjNum() != objnum))) { |
| 2456 len = pLenObj->GetInteger(); |
| 2457 } |
| 2458 |
| 2459 ToNextLine(); |
| 2460 FX_FILESIZE StreamStartPos = m_Pos; |
| 2461 if (pContext) { |
| 2462 pContext->m_DataStart = m_Pos; |
| 2463 } |
| 2464 |
| 2465 CPDF_CryptoHandler* pCryptoHandler = |
| 2466 objnum == (FX_DWORD)m_MetadataObjnum ? NULL : m_pCryptoHandler; |
| 2467 if (pCryptoHandler == NULL) { |
| 2468 pdfium::base::CheckedNumeric<FX_FILESIZE> pos = m_Pos; |
| 2469 pos += len; |
| 2470 if (pos.IsValid() && pos.ValueOrDie() < m_FileLen) { |
| 2471 m_Pos = pos.ValueOrDie(); |
| 2472 } |
| 2473 GetNextWord(); |
| 2474 if (m_WordSize < 9 || FXSYS_memcmp(m_WordBuffer, "endstream", 9)) { |
| 2475 m_Pos = StreamStartPos; |
| 2476 FX_FILESIZE offset = FindTag(FX_BSTRC("endstream"), 0); |
| 2477 if (offset >= 0) { |
| 2478 FX_FILESIZE curPos = m_Pos; |
| 2479 m_Pos = StreamStartPos; |
| 2480 FX_FILESIZE endobjOffset = FindTag(FX_BSTRC("endobj"), 0); |
| 2481 if (endobjOffset < offset && endobjOffset >= 0) { |
| 2482 offset = endobjOffset; |
| 2483 } else { |
| 2484 m_Pos = curPos; |
| 2485 } |
| 2486 uint8_t byte1, byte2; |
| 2487 GetCharAt(StreamStartPos + offset - 1, byte1); |
| 2488 GetCharAt(StreamStartPos + offset - 2, byte2); |
| 2489 if (byte1 == 0x0a && byte2 == 0x0d) { |
| 2490 len -= 2; |
| 2491 } else if (byte1 == 0x0a || byte1 == 0x0d) { |
| 2492 len--; |
| 2493 } |
| 2494 len = (FX_DWORD)offset; |
| 2495 pDict->SetAtInteger(FX_BSTRC("Length"), len); |
| 2496 } else { |
| 2497 m_Pos = StreamStartPos; |
| 2498 if (FindTag(FX_BSTRC("endobj"), 0) < 0) { |
| 2499 return NULL; |
| 2500 } |
| 2501 } |
| 2502 } |
| 2503 m_Pos = StreamStartPos; |
| 2504 } |
| 2505 CPDF_Stream* pStream; |
| 2506 uint8_t* pData = FX_Alloc(uint8_t, len); |
| 2507 ReadBlock(pData, len); |
| 2508 if (pCryptoHandler) { |
| 2509 CFX_BinaryBuf dest_buf; |
| 2510 dest_buf.EstimateSize(pCryptoHandler->DecryptGetSize(len)); |
| 2511 void* context = pCryptoHandler->DecryptStart(objnum, gennum); |
| 2512 pCryptoHandler->DecryptStream(context, pData, len, dest_buf); |
| 2513 pCryptoHandler->DecryptFinish(context, dest_buf); |
| 2514 FX_Free(pData); |
| 2515 pData = dest_buf.GetBuffer(); |
| 2516 len = dest_buf.GetSize(); |
| 2517 dest_buf.DetachBuffer(); |
| 2518 } |
| 2519 pStream = new CPDF_Stream(pData, len, pDict); |
| 2520 if (pContext) { |
| 2521 pContext->m_DataEnd = pContext->m_DataStart + len; |
| 2522 } |
| 2523 StreamStartPos = m_Pos; |
| 2524 GetNextWord(); |
| 2525 if (m_WordSize == 6 && 0 == FXSYS_memcmp(m_WordBuffer, "endobj", 6)) { |
| 2526 m_Pos = StreamStartPos; |
| 2527 } |
| 2528 return pStream; |
| 2529 } |
| 2530 void CPDF_SyntaxParser::InitParser(IFX_FileRead* pFileAccess, |
| 2531 FX_DWORD HeaderOffset) { |
| 2532 if (m_pFileBuf) { |
| 2533 FX_Free(m_pFileBuf); |
| 1686 m_pFileBuf = NULL; | 2534 m_pFileBuf = NULL; |
| 1687 m_BufSize = CPDF_ModuleMgr::kFileBufSize; | 2535 } |
| 1688 m_pFileBuf = NULL; | 2536 m_pFileBuf = FX_Alloc(uint8_t, m_BufSize); |
| 1689 m_MetadataObjnum = 0; | 2537 m_HeaderOffset = HeaderOffset; |
| 1690 m_dwWordPos = 0; | 2538 m_FileLen = pFileAccess->GetSize(); |
| 1691 m_bFileStream = FALSE; | 2539 m_Pos = 0; |
| 1692 } | 2540 m_pFileAccess = pFileAccess; |
| 1693 CPDF_SyntaxParser::~CPDF_SyntaxParser() | 2541 m_BufOffset = 0; |
| 1694 { | 2542 pFileAccess->ReadBlock( |
| 1695 if (m_pFileBuf) { | 2543 m_pFileBuf, 0, |
| 1696 FX_Free(m_pFileBuf); | 2544 (size_t)((FX_FILESIZE)m_BufSize > m_FileLen ? m_FileLen : m_BufSize)); |
| 1697 } | 2545 } |
| 1698 } | 2546 int32_t CPDF_SyntaxParser::GetDirectNum() { |
| 1699 FX_BOOL CPDF_SyntaxParser::GetCharAt(FX_FILESIZE pos, uint8_t& ch) | 2547 GetNextWord(); |
| 1700 { | 2548 if (!m_bIsNumber) { |
| 1701 FX_FILESIZE save_pos = m_Pos; | 2549 return 0; |
| 1702 m_Pos = pos; | 2550 } |
| 1703 FX_BOOL ret = GetNextChar(ch); | 2551 m_WordBuffer[m_WordSize] = 0; |
| 1704 m_Pos = save_pos; | 2552 return FXSYS_atoi((const FX_CHAR*)m_WordBuffer); |
| 1705 return ret; | 2553 } |
| 1706 } | 2554 FX_BOOL CPDF_SyntaxParser::IsWholeWord(FX_FILESIZE startpos, |
| 1707 FX_BOOL CPDF_SyntaxParser::GetNextChar(uint8_t& ch) | 2555 FX_FILESIZE limit, |
| 1708 { | 2556 const uint8_t* tag, |
| 1709 FX_FILESIZE pos = m_Pos + m_HeaderOffset; | 2557 FX_DWORD taglen) { |
| 1710 if (pos >= m_FileLen) { | 2558 uint8_t type = PDF_CharType[tag[0]]; |
| 2559 FX_BOOL bCheckLeft = type != 'D' && type != 'W'; |
| 2560 type = PDF_CharType[tag[taglen - 1]]; |
| 2561 FX_BOOL bCheckRight = type != 'D' && type != 'W'; |
| 2562 uint8_t ch; |
| 2563 if (bCheckRight && startpos + (int32_t)taglen <= limit && |
| 2564 GetCharAt(startpos + (int32_t)taglen, ch)) { |
| 2565 uint8_t type = PDF_CharType[ch]; |
| 2566 if (type == 'N' || type == 'R') { |
| 2567 return FALSE; |
| 2568 } |
| 2569 } |
| 2570 if (bCheckLeft && startpos > 0 && GetCharAt(startpos - 1, ch)) { |
| 2571 uint8_t type = PDF_CharType[ch]; |
| 2572 if (type == 'N' || type == 'R') { |
| 2573 return FALSE; |
| 2574 } |
| 2575 } |
| 2576 return TRUE; |
| 2577 } |
| 2578 FX_BOOL CPDF_SyntaxParser::SearchWord(const CFX_ByteStringC& tag, |
| 2579 FX_BOOL bWholeWord, |
| 2580 FX_BOOL bForward, |
| 2581 FX_FILESIZE limit) { |
| 2582 int32_t taglen = tag.GetLength(); |
| 2583 if (taglen == 0) { |
| 2584 return FALSE; |
| 2585 } |
| 2586 FX_FILESIZE pos = m_Pos; |
| 2587 int32_t offset = 0; |
| 2588 if (!bForward) { |
| 2589 offset = taglen - 1; |
| 2590 } |
| 2591 const uint8_t* tag_data = tag.GetPtr(); |
| 2592 uint8_t byte; |
| 2593 while (1) { |
| 2594 if (bForward) { |
| 2595 if (limit) { |
| 2596 if (pos >= m_Pos + limit) { |
| 2597 return FALSE; |
| 2598 } |
| 2599 } |
| 2600 if (!GetCharAt(pos, byte)) { |
| 1711 return FALSE; | 2601 return FALSE; |
| 1712 } | 2602 } |
| 1713 if (m_BufOffset >= pos || (FX_FILESIZE)(m_BufOffset + m_BufSize) <= pos) { | 2603 } else { |
| 1714 FX_FILESIZE read_pos = pos; | 2604 if (limit) { |
| 1715 FX_DWORD read_size = m_BufSize; | 2605 if (pos <= m_Pos - limit) { |
| 1716 if ((FX_FILESIZE)read_size > m_FileLen) { | 2606 return FALSE; |
| 1717 read_size = (FX_DWORD)m_FileLen; | 2607 } |
| 1718 } | 2608 } |
| 1719 if ((FX_FILESIZE)(read_pos + read_size) > m_FileLen) { | 2609 if (!GetCharAtBackward(pos, byte)) { |
| 1720 if (m_FileLen < (FX_FILESIZE)read_size) { | 2610 return FALSE; |
| 1721 read_pos = 0; | 2611 } |
| 1722 read_size = (FX_DWORD)m_FileLen; | 2612 } |
| 2613 if (byte == tag_data[offset]) { |
| 2614 if (bForward) { |
| 2615 offset++; |
| 2616 if (offset < taglen) { |
| 2617 pos++; |
| 2618 continue; |
| 2619 } |
| 2620 } else { |
| 2621 offset--; |
| 2622 if (offset >= 0) { |
| 2623 pos--; |
| 2624 continue; |
| 2625 } |
| 2626 } |
| 2627 FX_FILESIZE startpos = bForward ? pos - taglen + 1 : pos; |
| 2628 if (!bWholeWord || IsWholeWord(startpos, limit, tag.GetPtr(), taglen)) { |
| 2629 m_Pos = startpos; |
| 2630 return TRUE; |
| 2631 } |
| 2632 } |
| 2633 if (bForward) { |
| 2634 offset = byte == tag_data[0] ? 1 : 0; |
| 2635 pos++; |
| 2636 } else { |
| 2637 offset = byte == tag_data[taglen - 1] ? taglen - 2 : taglen - 1; |
| 2638 pos--; |
| 2639 } |
| 2640 if (pos < 0) { |
| 2641 return FALSE; |
| 2642 } |
| 2643 } |
| 2644 return FALSE; |
| 2645 } |
| 2646 struct _SearchTagRecord { |
| 2647 const uint8_t* m_pTag; |
| 2648 FX_DWORD m_Len; |
| 2649 FX_DWORD m_Offset; |
| 2650 }; |
| 2651 int32_t CPDF_SyntaxParser::SearchMultiWord(const CFX_ByteStringC& tags, |
| 2652 FX_BOOL bWholeWord, |
| 2653 FX_FILESIZE limit) { |
| 2654 int32_t ntags = 1, i; |
| 2655 for (i = 0; i < tags.GetLength(); i++) |
| 2656 if (tags[i] == 0) { |
| 2657 ntags++; |
| 2658 } |
| 2659 _SearchTagRecord* pPatterns = FX_Alloc(_SearchTagRecord, ntags); |
| 2660 FX_DWORD start = 0, itag = 0, max_len = 0; |
| 2661 for (i = 0; i <= tags.GetLength(); i++) { |
| 2662 if (tags[i] == 0) { |
| 2663 FX_DWORD len = i - start; |
| 2664 if (len > max_len) { |
| 2665 max_len = len; |
| 2666 } |
| 2667 pPatterns[itag].m_pTag = tags.GetPtr() + start; |
| 2668 pPatterns[itag].m_Len = len; |
| 2669 pPatterns[itag].m_Offset = 0; |
| 2670 start = i + 1; |
| 2671 itag++; |
| 2672 } |
| 2673 } |
| 2674 FX_FILESIZE pos = m_Pos; |
| 2675 uint8_t byte; |
| 2676 GetCharAt(pos++, byte); |
| 2677 int32_t found = -1; |
| 2678 while (1) { |
| 2679 for (i = 0; i < ntags; i++) { |
| 2680 if (pPatterns[i].m_pTag[pPatterns[i].m_Offset] == byte) { |
| 2681 pPatterns[i].m_Offset++; |
| 2682 if (pPatterns[i].m_Offset == pPatterns[i].m_Len) { |
| 2683 if (!bWholeWord || |
| 2684 IsWholeWord(pos - pPatterns[i].m_Len, limit, pPatterns[i].m_pTag, |
| 2685 pPatterns[i].m_Len)) { |
| 2686 found = i; |
| 2687 goto end; |
| 2688 } else { |
| 2689 if (pPatterns[i].m_pTag[0] == byte) { |
| 2690 pPatterns[i].m_Offset = 1; |
| 1723 } else { | 2691 } else { |
| 1724 read_pos = m_FileLen - read_size; | 2692 pPatterns[i].m_Offset = 0; |
| 1725 } | 2693 } |
| 1726 } | 2694 } |
| 1727 if (!m_pFileAccess->ReadBlock(m_pFileBuf, read_pos, read_size)) { | 2695 } |
| 1728 return FALSE; | 2696 } else { |
| 1729 } | 2697 if (pPatterns[i].m_pTag[0] == byte) { |
| 1730 m_BufOffset = read_pos; | 2698 pPatterns[i].m_Offset = 1; |
| 1731 } | |
| 1732 ch = m_pFileBuf[pos - m_BufOffset]; | |
| 1733 m_Pos ++; | |
| 1734 return TRUE; | |
| 1735 } | |
| 1736 FX_BOOL CPDF_SyntaxParser::GetCharAtBackward(FX_FILESIZE pos, uint8_t& ch) | |
| 1737 { | |
| 1738 pos += m_HeaderOffset; | |
| 1739 if (pos >= m_FileLen) { | |
| 1740 return FALSE; | |
| 1741 } | |
| 1742 if (m_BufOffset >= pos || (FX_FILESIZE)(m_BufOffset + m_BufSize) <= pos) { | |
| 1743 FX_FILESIZE read_pos; | |
| 1744 if (pos < (FX_FILESIZE)m_BufSize) { | |
| 1745 read_pos = 0; | |
| 1746 } else { | 2699 } else { |
| 1747 read_pos = pos - m_BufSize + 1; | 2700 pPatterns[i].m_Offset = 0; |
| 1748 } | 2701 } |
| 1749 FX_DWORD read_size = m_BufSize; | 2702 } |
| 1750 if ((FX_FILESIZE)(read_pos + read_size) > m_FileLen) { | 2703 } |
| 1751 if (m_FileLen < (FX_FILESIZE)read_size) { | 2704 if (limit && pos >= m_Pos + limit) { |
| 1752 read_pos = 0; | 2705 goto end; |
| 1753 read_size = (FX_DWORD)m_FileLen; | 2706 } |
| 1754 } else { | 2707 if (!GetCharAt(pos, byte)) { |
| 1755 read_pos = m_FileLen - read_size; | 2708 goto end; |
| 1756 } | 2709 } |
| 1757 } | 2710 pos++; |
| 1758 if (!m_pFileAccess->ReadBlock(m_pFileBuf, read_pos, read_size)) { | 2711 } |
| 1759 return FALSE; | 2712 end: |
| 1760 } | 2713 FX_Free(pPatterns); |
| 1761 m_BufOffset = read_pos; | 2714 return found; |
| 1762 } | 2715 } |
| 1763 ch = m_pFileBuf[pos - m_BufOffset]; | 2716 FX_FILESIZE CPDF_SyntaxParser::FindTag(const CFX_ByteStringC& tag, |
| 1764 return TRUE; | 2717 FX_FILESIZE limit) { |
| 1765 } | 2718 int32_t taglen = tag.GetLength(); |
| 1766 FX_BOOL CPDF_SyntaxParser::ReadBlock(uint8_t* pBuf, FX_DWORD size) | 2719 int32_t match = 0; |
| 1767 { | 2720 limit += m_Pos; |
| 1768 if (!m_pFileAccess->ReadBlock(pBuf, m_Pos + m_HeaderOffset, size)) { | 2721 FX_FILESIZE startpos = m_Pos; |
| 1769 return FALSE; | 2722 while (1) { |
| 1770 } | |
| 1771 m_Pos += size; | |
| 1772 return TRUE; | |
| 1773 } | |
| 1774 #define MAX_WORD_BUFFER 256 | |
| 1775 void CPDF_SyntaxParser::GetNextWord() | |
| 1776 { | |
| 1777 m_WordSize = 0; | |
| 1778 m_bIsNumber = TRUE; | |
| 1779 uint8_t ch; | 2723 uint8_t ch; |
| 1780 if (!GetNextChar(ch)) { | 2724 if (!GetNextChar(ch)) { |
| 1781 return; | 2725 return -1; |
| 1782 } | 2726 } |
| 1783 uint8_t type = PDF_CharType[ch]; | 2727 if (ch == tag[match]) { |
| 1784 while (1) { | 2728 match++; |
| 1785 while (type == 'W') { | 2729 if (match == taglen) { |
| 1786 if (!GetNextChar(ch)) { | 2730 return m_Pos - startpos - taglen; |
| 1787 return; | 2731 } |
| 1788 } | 2732 } else { |
| 1789 type = PDF_CharType[ch]; | 2733 match = ch == tag[0] ? 1 : 0; |
| 1790 } | 2734 } |
| 1791 if (ch != '%') { | 2735 if (limit && m_Pos == limit) { |
| 1792 break; | 2736 return -1; |
| 1793 } | 2737 } |
| 1794 while (1) { | 2738 } |
| 1795 if (!GetNextChar(ch)) { | 2739 return -1; |
| 1796 return; | 2740 } |
| 1797 } | 2741 void CPDF_SyntaxParser::GetBinary(uint8_t* buffer, FX_DWORD size) { |
| 1798 if (ch == '\r' || ch == '\n') { | 2742 FX_DWORD offset = 0; |
| 1799 break; | 2743 uint8_t ch; |
| 1800 } | 2744 while (1) { |
| 1801 } | |
| 1802 type = PDF_CharType[ch]; | |
| 1803 } | |
| 1804 if (type == 'D') { | |
| 1805 m_bIsNumber = FALSE; | |
| 1806 m_WordBuffer[m_WordSize++] = ch; | |
| 1807 if (ch == '/') { | |
| 1808 while (1) { | |
| 1809 if (!GetNextChar(ch)) { | |
| 1810 return; | |
| 1811 } | |
| 1812 type = PDF_CharType[ch]; | |
| 1813 if (type != 'R' && type != 'N') { | |
| 1814 m_Pos --; | |
| 1815 return; | |
| 1816 } | |
| 1817 if (m_WordSize < MAX_WORD_BUFFER) { | |
| 1818 m_WordBuffer[m_WordSize++] = ch; | |
| 1819 } | |
| 1820 } | |
| 1821 } else if (ch == '<') { | |
| 1822 if (!GetNextChar(ch)) { | |
| 1823 return; | |
| 1824 } | |
| 1825 if (ch == '<') { | |
| 1826 m_WordBuffer[m_WordSize++] = ch; | |
| 1827 } else { | |
| 1828 m_Pos --; | |
| 1829 } | |
| 1830 } else if (ch == '>') { | |
| 1831 if (!GetNextChar(ch)) { | |
| 1832 return; | |
| 1833 } | |
| 1834 if (ch == '>') { | |
| 1835 m_WordBuffer[m_WordSize++] = ch; | |
| 1836 } else { | |
| 1837 m_Pos --; | |
| 1838 } | |
| 1839 } | |
| 1840 return; | |
| 1841 } | |
| 1842 while (1) { | |
| 1843 if (m_WordSize < MAX_WORD_BUFFER) { | |
| 1844 m_WordBuffer[m_WordSize++] = ch; | |
| 1845 } | |
| 1846 if (type != 'N') { | |
| 1847 m_bIsNumber = FALSE; | |
| 1848 } | |
| 1849 if (!GetNextChar(ch)) { | |
| 1850 return; | |
| 1851 } | |
| 1852 type = PDF_CharType[ch]; | |
| 1853 if (type == 'D' || type == 'W') { | |
| 1854 m_Pos --; | |
| 1855 break; | |
| 1856 } | |
| 1857 } | |
| 1858 } | |
| 1859 CFX_ByteString CPDF_SyntaxParser::ReadString() | |
| 1860 { | |
| 1861 uint8_t ch; | |
| 1862 if (!GetNextChar(ch)) { | 2745 if (!GetNextChar(ch)) { |
| 1863 return CFX_ByteString(); | 2746 return; |
| 1864 } | 2747 } |
| 1865 CFX_ByteTextBuf buf; | 2748 buffer[offset++] = ch; |
| 1866 int32_t parlevel = 0; | 2749 if (offset == size) { |
| 1867 int32_t status = 0, iEscCode = 0; | 2750 break; |
| 1868 while (1) { | 2751 } |
| 1869 switch (status) { | 2752 } |
| 1870 case 0: | 2753 } |
| 1871 if (ch == ')') { | 2754 |
| 1872 if (parlevel == 0) { | 2755 class CPDF_DataAvail final : public IPDF_DataAvail { |
| 1873 return buf.GetByteString(); | 2756 public: |
| 1874 } | 2757 CPDF_DataAvail(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRead); |
| 1875 parlevel --; | 2758 ~CPDF_DataAvail(); |
| 1876 buf.AppendChar(')'); | 2759 |
| 1877 } else if (ch == '(') { | 2760 virtual FX_BOOL IsDocAvail(IFX_DownloadHints* pHints) override; |
| 1878 parlevel ++; | 2761 |
| 1879 buf.AppendChar('('); | 2762 virtual void SetDocument(CPDF_Document* pDoc) override; |
| 1880 } else if (ch == '\\') { | 2763 |
| 1881 status = 1; | 2764 virtual FX_BOOL IsPageAvail(int iPage, IFX_DownloadHints* pHints) override; |
| 1882 } else { | 2765 |
| 1883 buf.AppendChar(ch); | 2766 virtual int32_t IsFormAvail(IFX_DownloadHints* pHints) override; |
| 1884 } | 2767 |
| 1885 break; | 2768 virtual int32_t IsLinearizedPDF() override; |
| 1886 case 1: | 2769 |
| 1887 if (ch >= '0' && ch <= '7') { | 2770 virtual FX_BOOL IsLinearized() override { return m_bLinearized; } |
| 1888 iEscCode = ch - '0'; | 2771 |
| 1889 status = 2; | 2772 virtual void GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, |
| 1890 break; | 2773 FX_DWORD* pSize) override; |
| 1891 } | 2774 |
| 1892 if (ch == 'n') { | 2775 protected: |
| 1893 buf.AppendChar('\n'); | 2776 static const int kMaxDataAvailRecursionDepth = 64; |
| 1894 } else if (ch == 'r') { | 2777 static int s_CurrentDataAvailRecursionDepth; |
| 1895 buf.AppendChar('\r'); | 2778 |
| 1896 } else if (ch == 't') { | 2779 FX_DWORD GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset); |
| 1897 buf.AppendChar('\t'); | 2780 FX_BOOL IsObjectsAvail(CFX_PtrArray& obj_array, |
| 1898 } else if (ch == 'b') { | 2781 FX_BOOL bParsePage, |
| 1899 buf.AppendChar('\b'); | 2782 IFX_DownloadHints* pHints, |
| 1900 } else if (ch == 'f') { | 2783 CFX_PtrArray& ret_array); |
| 1901 buf.AppendChar('\f'); | 2784 FX_BOOL CheckDocStatus(IFX_DownloadHints* pHints); |
| 1902 } else if (ch == '\r') { | 2785 FX_BOOL CheckHeader(IFX_DownloadHints* pHints); |
| 1903 status = 4; | 2786 FX_BOOL CheckFirstPage(IFX_DownloadHints* pHints); |
| 1904 break; | 2787 FX_BOOL CheckEnd(IFX_DownloadHints* pHints); |
| 1905 } else if (ch == '\n') { | 2788 FX_BOOL CheckCrossRef(IFX_DownloadHints* pHints); |
| 1906 } else { | 2789 FX_BOOL CheckCrossRefItem(IFX_DownloadHints* pHints); |
| 1907 buf.AppendChar(ch); | 2790 FX_BOOL CheckTrailer(IFX_DownloadHints* pHints); |
| 1908 } | 2791 FX_BOOL CheckRoot(IFX_DownloadHints* pHints); |
| 1909 status = 0; | 2792 FX_BOOL CheckInfo(IFX_DownloadHints* pHints); |
| 1910 break; | 2793 FX_BOOL CheckPages(IFX_DownloadHints* pHints); |
| 1911 case 2: | 2794 FX_BOOL CheckPage(IFX_DownloadHints* pHints); |
| 1912 if (ch >= '0' && ch <= '7') { | 2795 FX_BOOL CheckResources(IFX_DownloadHints* pHints); |
| 1913 iEscCode = iEscCode * 8 + ch - '0'; | 2796 FX_BOOL CheckAnnots(IFX_DownloadHints* pHints); |
| 1914 status = 3; | 2797 FX_BOOL CheckAcroForm(IFX_DownloadHints* pHints); |
| 1915 } else { | 2798 FX_BOOL CheckAcroFormSubObject(IFX_DownloadHints* pHints); |
| 1916 buf.AppendChar(iEscCode); | 2799 FX_BOOL CheckTrailerAppend(IFX_DownloadHints* pHints); |
| 1917 status = 0; | 2800 FX_BOOL CheckPageStatus(IFX_DownloadHints* pHints); |
| 1918 continue; | 2801 FX_BOOL CheckAllCrossRefStream(IFX_DownloadHints* pHints); |
| 1919 } | 2802 |
| 1920 break; | 2803 int32_t CheckCrossRefStream(IFX_DownloadHints* pHints, |
| 1921 case 3: | 2804 FX_FILESIZE& xref_offset); |
| 1922 if (ch >= '0' && ch <= '7') { | 2805 FX_BOOL IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen); |
| 1923 iEscCode = iEscCode * 8 + ch - '0'; | 2806 void SetStartOffset(FX_FILESIZE dwOffset); |
| 1924 buf.AppendChar(iEscCode); | 2807 FX_BOOL GetNextToken(CFX_ByteString& token); |
| 1925 status = 0; | 2808 FX_BOOL GetNextChar(uint8_t& ch); |
| 1926 } else { | 2809 CPDF_Object* ParseIndirectObjectAt(FX_FILESIZE pos, FX_DWORD objnum); |
| 1927 buf.AppendChar(iEscCode); | 2810 CPDF_Object* GetObject(FX_DWORD objnum, |
| 1928 status = 0; | 2811 IFX_DownloadHints* pHints, |
| 1929 continue; | 2812 FX_BOOL* pExistInFile); |
| 1930 } | 2813 FX_BOOL GetPageKids(CPDF_Parser* pParser, CPDF_Object* pPages); |
| 1931 break; | 2814 FX_BOOL PreparePageItem(); |
| 1932 case 4: | 2815 FX_BOOL LoadPages(IFX_DownloadHints* pHints); |
| 1933 status = 0; | 2816 FX_BOOL LoadAllXref(IFX_DownloadHints* pHints); |
| 1934 if (ch != '\n') { | 2817 FX_BOOL LoadAllFile(IFX_DownloadHints* pHints); |
| 1935 continue; | 2818 FX_BOOL CheckLinearizedData(IFX_DownloadHints* pHints); |
| 1936 } | 2819 FX_BOOL CheckFileResources(IFX_DownloadHints* pHints); |
| 1937 break; | 2820 FX_BOOL CheckPageAnnots(int iPage, IFX_DownloadHints* pHints); |
| 1938 } | 2821 |
| 1939 if (!GetNextChar(ch)) { | 2822 FX_BOOL CheckLinearizedFirstPage(int iPage, IFX_DownloadHints* pHints); |
| 1940 break; | 2823 FX_BOOL HaveResourceAncestor(CPDF_Dictionary* pDict); |
| 1941 } | 2824 FX_BOOL CheckPage(int32_t iPage, IFX_DownloadHints* pHints); |
| 1942 } | 2825 FX_BOOL LoadDocPages(IFX_DownloadHints* pHints); |
| 1943 GetNextChar(ch); | 2826 FX_BOOL LoadDocPage(int32_t iPage, IFX_DownloadHints* pHints); |
| 1944 return buf.GetByteString(); | 2827 FX_BOOL CheckPageNode(CPDF_PageNode& pageNodes, |
| 1945 } | 2828 int32_t iPage, |
| 1946 CFX_ByteString CPDF_SyntaxParser::ReadHexString() | 2829 int32_t& iCount, |
| 1947 { | 2830 IFX_DownloadHints* pHints); |
| 1948 uint8_t ch; | 2831 FX_BOOL CheckUnkownPageNode(FX_DWORD dwPageNo, |
| 1949 if (!GetNextChar(ch)) { | 2832 CPDF_PageNode* pPageNode, |
| 1950 return CFX_ByteString(); | 2833 IFX_DownloadHints* pHints); |
| 1951 } | 2834 FX_BOOL CheckArrayPageNode(FX_DWORD dwPageNo, |
| 1952 CFX_BinaryBuf buf; | 2835 CPDF_PageNode* pPageNode, |
| 1953 FX_BOOL bFirst = TRUE; | 2836 IFX_DownloadHints* pHints); |
| 1954 uint8_t code = 0; | 2837 FX_BOOL CheckPageCount(IFX_DownloadHints* pHints); |
| 1955 while (1) { | 2838 FX_BOOL IsFirstCheck(int iPage); |
| 1956 if (ch == '>') { | 2839 void ResetFirstCheck(int iPage); |
| 1957 break; | 2840 |
| 1958 } | 2841 CPDF_Parser m_parser; |
| 1959 if (ch >= '0' && ch <= '9') { | 2842 |
| 1960 if (bFirst) { | 2843 CPDF_SyntaxParser m_syntaxParser; |
| 1961 code = (ch - '0') * 16; | 2844 |
| 1962 } else { | 2845 CPDF_Object* m_pRoot; |
| 1963 code += ch - '0'; | 2846 |
| 1964 buf.AppendByte((uint8_t)code); | 2847 FX_DWORD m_dwRootObjNum; |
| 1965 } | 2848 |
| 1966 bFirst = !bFirst; | 2849 FX_DWORD m_dwInfoObjNum; |
| 1967 } else if (ch >= 'A' && ch <= 'F') { | 2850 |
| 1968 if (bFirst) { | 2851 CPDF_Object* m_pLinearized; |
| 1969 code = (ch - 'A' + 10) * 16; | 2852 |
| 1970 } else { | 2853 CPDF_Object* m_pTrailer; |
| 1971 code += ch - 'A' + 10; | 2854 |
| 1972 buf.AppendByte((uint8_t)code); | 2855 FX_BOOL m_bDocAvail; |
| 1973 } | 2856 |
| 1974 bFirst = !bFirst; | 2857 FX_FILESIZE m_dwHeaderOffset; |
| 1975 } else if (ch >= 'a' && ch <= 'f') { | 2858 |
| 1976 if (bFirst) { | 2859 FX_FILESIZE m_dwLastXRefOffset; |
| 1977 code = (ch - 'a' + 10) * 16; | 2860 |
| 1978 } else { | 2861 FX_FILESIZE m_dwXRefOffset; |
| 1979 code += ch - 'a' + 10; | 2862 |
| 1980 buf.AppendByte((uint8_t)code); | 2863 FX_FILESIZE m_dwTrailerOffset; |
| 1981 } | 2864 |
| 1982 bFirst = !bFirst; | 2865 FX_FILESIZE m_dwCurrentOffset; |
| 1983 } | 2866 |
| 1984 if (!GetNextChar(ch)) { | 2867 PDF_DATAAVAIL_STATUS m_docStatus; |
| 1985 break; | 2868 |
| 1986 } | 2869 FX_FILESIZE m_dwFileLen; |
| 1987 } | 2870 |
| 1988 if (!bFirst) { | 2871 CPDF_Document* m_pDocument; |
| 1989 buf.AppendByte((uint8_t)code); | 2872 |
| 1990 } | 2873 CPDF_SortObjNumArray m_objnum_array; |
| 1991 return buf.GetByteString(); | 2874 |
| 1992 } | 2875 CFX_PtrArray m_objs_array; |
| 1993 void CPDF_SyntaxParser::ToNextLine() | 2876 |
| 1994 { | 2877 FX_FILESIZE m_Pos; |
| 1995 uint8_t ch; | 2878 |
| 1996 while (GetNextChar(ch)) { | 2879 FX_FILESIZE m_bufferOffset; |
| 1997 if (ch == '\n') { | 2880 |
| 1998 break; | 2881 FX_DWORD m_bufferSize; |
| 1999 } | 2882 |
| 2000 if (ch == '\r') { | 2883 CFX_ByteString m_WordBuf; |
| 2001 GetNextChar(ch); | 2884 |
| 2002 if (ch != '\n') { | 2885 uint8_t m_WordBuffer[257]; |
| 2003 --m_Pos; | 2886 |
| 2004 } | 2887 FX_DWORD m_WordSize; |
| 2005 break; | 2888 |
| 2006 } | 2889 uint8_t m_bufferData[512]; |
| 2007 } | 2890 |
| 2008 } | 2891 CFX_FileSizeArray m_CrossOffset; |
| 2009 void CPDF_SyntaxParser::ToNextWord() | 2892 |
| 2010 { | 2893 CFX_DWordArray m_XRefStreamList; |
| 2011 uint8_t ch; | 2894 |
| 2012 if (!GetNextChar(ch)) { | 2895 CFX_DWordArray m_PageObjList; |
| 2013 return; | 2896 |
| 2014 } | 2897 FX_DWORD m_PagesObjNum; |
| 2015 uint8_t type = PDF_CharType[ch]; | 2898 |
| 2016 while (1) { | 2899 FX_BOOL m_bLinearized; |
| 2017 while (type == 'W') { | 2900 |
| 2018 m_dwWordPos = m_Pos; | 2901 FX_DWORD m_dwFirstPageNo; |
| 2019 if (!GetNextChar(ch)) { | 2902 |
| 2020 return; | 2903 FX_BOOL m_bLinearedDataOK; |
| 2021 } | 2904 |
| 2022 type = PDF_CharType[ch]; | 2905 FX_BOOL m_bMainXRefLoadTried; |
| 2023 } | 2906 |
| 2024 if (ch != '%') { | 2907 FX_BOOL m_bMainXRefLoadedOK; |
| 2025 break; | 2908 |
| 2026 } | 2909 FX_BOOL m_bPagesTreeLoad; |
| 2027 while (1) { | 2910 |
| 2028 if (!GetNextChar(ch)) { | 2911 FX_BOOL m_bPagesLoad; |
| 2029 return; | 2912 |
| 2030 } | 2913 CPDF_Parser* m_pCurrentParser; |
| 2031 if (ch == '\r' || ch == '\n') { | 2914 |
| 2032 break; | 2915 FX_FILESIZE m_dwCurrentXRefSteam; |
| 2033 } | 2916 |
| 2034 } | 2917 FX_BOOL m_bAnnotsLoad; |
| 2035 type = PDF_CharType[ch]; | 2918 |
| 2036 } | 2919 FX_BOOL m_bHaveAcroForm; |
| 2037 m_Pos --; | 2920 |
| 2038 } | 2921 FX_DWORD m_dwAcroFormObjNum; |
| 2039 CFX_ByteString CPDF_SyntaxParser::GetNextWord(FX_BOOL& bIsNumber) | 2922 |
| 2040 { | 2923 FX_BOOL m_bAcroFormLoad; |
| 2041 GetNextWord(); | 2924 |
| 2042 bIsNumber = m_bIsNumber; | 2925 CPDF_Object* m_pAcroForm; |
| 2043 return CFX_ByteString((const FX_CHAR*)m_WordBuffer, m_WordSize); | 2926 |
| 2044 } | 2927 CFX_PtrArray m_arrayAcroforms; |
| 2045 CFX_ByteString CPDF_SyntaxParser::GetKeyword() | 2928 |
| 2046 { | 2929 CPDF_Dictionary* m_pPageDict; |
| 2047 GetNextWord(); | 2930 |
| 2048 return CFX_ByteString((const FX_CHAR*)m_WordBuffer, m_WordSize); | 2931 CPDF_Object* m_pPageResource; |
| 2049 } | 2932 |
| 2050 CPDF_Object* CPDF_SyntaxParser::GetObject(CPDF_IndirectObjects* pObjList, FX_DWO
RD objnum, FX_DWORD gennum, PARSE_CONTEXT* pContext, FX_BOOL bDecrypt) | 2933 FX_BOOL m_bNeedDownLoadResource; |
| 2051 { | 2934 |
| 2052 CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth); | 2935 FX_BOOL m_bPageLoadedOK; |
| 2053 if (++s_CurrentRecursionDepth > kParserMaxRecursionDepth) { | 2936 |
| 2054 return NULL; | 2937 FX_BOOL m_bLinearizedFormParamLoad; |
| 2055 } | 2938 |
| 2056 FX_FILESIZE SavedPos = m_Pos; | 2939 CFX_PtrArray m_PagesArray; |
| 2057 FX_BOOL bTypeOnly = pContext && (pContext->m_Flags & PDFPARSE_TYPEONLY); | 2940 |
| 2058 FX_BOOL bIsNumber; | 2941 FX_DWORD m_dwEncryptObjNum; |
| 2059 CFX_ByteString word = GetNextWord(bIsNumber); | 2942 |
| 2060 if (word.GetLength() == 0) { | 2943 FX_FILESIZE m_dwPrevXRefOffset; |
| 2061 if (bTypeOnly) { | 2944 |
| 2062 return (CPDF_Object*)PDFOBJ_INVALID; | 2945 FX_BOOL m_bTotalLoadPageTree; |
| 2063 } | 2946 |
| 2064 return NULL; | 2947 FX_BOOL m_bCurPageDictLoadOK; |
| 2065 } | 2948 |
| 2066 if (bIsNumber) { | 2949 CPDF_PageNode m_pageNodes; |
| 2067 FX_FILESIZE SavedPos = m_Pos; | 2950 |
| 2068 CFX_ByteString nextword = GetNextWord(bIsNumber); | 2951 CFX_CMapDWordToDWord* m_pageMapCheckState; |
| 2069 if (bIsNumber) { | 2952 |
| 2070 CFX_ByteString nextword2 = GetNextWord(bIsNumber); | 2953 CFX_CMapDWordToDWord* m_pagesLoadState; |
| 2071 if (nextword2 == FX_BSTRC("R")) { | |
| 2072 FX_DWORD objnum = FXSYS_atoi(word); | |
| 2073 if (bTypeOnly) { | |
| 2074 return (CPDF_Object*)PDFOBJ_REFERENCE; | |
| 2075 } | |
| 2076 return new CPDF_Reference(pObjList, objnum); | |
| 2077 } | |
| 2078 } | |
| 2079 m_Pos = SavedPos; | |
| 2080 if (bTypeOnly) { | |
| 2081 return (CPDF_Object*)PDFOBJ_NUMBER; | |
| 2082 } | |
| 2083 return CPDF_Number::Create(word); | |
| 2084 } | |
| 2085 if (word == FX_BSTRC("true") || word == FX_BSTRC("false")) { | |
| 2086 if (bTypeOnly) { | |
| 2087 return (CPDF_Object*)PDFOBJ_BOOLEAN; | |
| 2088 } | |
| 2089 return CPDF_Boolean::Create(word == FX_BSTRC("true")); | |
| 2090 } | |
| 2091 if (word == FX_BSTRC("null")) { | |
| 2092 if (bTypeOnly) { | |
| 2093 return (CPDF_Object*)PDFOBJ_NULL; | |
| 2094 } | |
| 2095 return CPDF_Null::Create(); | |
| 2096 } | |
| 2097 if (word == FX_BSTRC("(")) { | |
| 2098 if (bTypeOnly) { | |
| 2099 return (CPDF_Object*)PDFOBJ_STRING; | |
| 2100 } | |
| 2101 CFX_ByteString str = ReadString(); | |
| 2102 if (m_pCryptoHandler && bDecrypt) { | |
| 2103 m_pCryptoHandler->Decrypt(objnum, gennum, str); | |
| 2104 } | |
| 2105 return CPDF_String::Create(str, FALSE); | |
| 2106 } | |
| 2107 if (word == FX_BSTRC("<")) { | |
| 2108 if (bTypeOnly) { | |
| 2109 return (CPDF_Object*)PDFOBJ_STRING; | |
| 2110 } | |
| 2111 CFX_ByteString str = ReadHexString(); | |
| 2112 if (m_pCryptoHandler && bDecrypt) { | |
| 2113 m_pCryptoHandler->Decrypt(objnum, gennum, str); | |
| 2114 } | |
| 2115 return CPDF_String::Create(str, TRUE); | |
| 2116 } | |
| 2117 if (word == FX_BSTRC("[")) { | |
| 2118 if (bTypeOnly) { | |
| 2119 return (CPDF_Object*)PDFOBJ_ARRAY; | |
| 2120 } | |
| 2121 CPDF_Array* pArray = CPDF_Array::Create(); | |
| 2122 while (1) { | |
| 2123 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum); | |
| 2124 if (pObj == NULL) { | |
| 2125 return pArray; | |
| 2126 } | |
| 2127 pArray->Add(pObj); | |
| 2128 } | |
| 2129 } | |
| 2130 if (word[0] == '/') { | |
| 2131 if (bTypeOnly) { | |
| 2132 return (CPDF_Object*)PDFOBJ_NAME; | |
| 2133 } | |
| 2134 return CPDF_Name::Create( | |
| 2135 PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))); | |
| 2136 } | |
| 2137 if (word == FX_BSTRC("<<")) { | |
| 2138 if (bTypeOnly) { | |
| 2139 return (CPDF_Object*)PDFOBJ_DICTIONARY; | |
| 2140 } | |
| 2141 if (pContext) { | |
| 2142 pContext->m_DictStart = SavedPos; | |
| 2143 } | |
| 2144 CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); | |
| 2145 int32_t nKeys = 0; | |
| 2146 FX_FILESIZE dwSignValuePos = 0; | |
| 2147 while (1) { | |
| 2148 FX_BOOL bIsNumber; | |
| 2149 CFX_ByteString key = GetNextWord(bIsNumber); | |
| 2150 if (key.IsEmpty()) { | |
| 2151 if (pDict) | |
| 2152 pDict->Release(); | |
| 2153 return NULL; | |
| 2154 } | |
| 2155 FX_FILESIZE SavedPos = m_Pos - key.GetLength(); | |
| 2156 if (key == FX_BSTRC(">>")) { | |
| 2157 break; | |
| 2158 } | |
| 2159 if (key == FX_BSTRC("endobj")) { | |
| 2160 m_Pos = SavedPos; | |
| 2161 break; | |
| 2162 } | |
| 2163 if (key[0] != '/') { | |
| 2164 continue; | |
| 2165 } | |
| 2166 nKeys ++; | |
| 2167 key = PDF_NameDecode(key); | |
| 2168 if (key == FX_BSTRC("/Contents")) { | |
| 2169 dwSignValuePos = m_Pos; | |
| 2170 } | |
| 2171 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum); | |
| 2172 if (pObj == NULL) { | |
| 2173 continue; | |
| 2174 } | |
| 2175 if (key.GetLength() >= 1) { | |
| 2176 if (nKeys < 32) { | |
| 2177 pDict->SetAt(CFX_ByteStringC(key.c_str() + 1, key.GetLength(
) - 1), pObj); | |
| 2178 } else { | |
| 2179 pDict->AddValue(CFX_ByteStringC(key.c_str() + 1, key.GetLeng
th() - 1), pObj); | |
| 2180 } | |
| 2181 } | |
| 2182 } | |
| 2183 if (IsSignatureDict(pDict)) { | |
| 2184 FX_FILESIZE dwSavePos = m_Pos; | |
| 2185 m_Pos = dwSignValuePos; | |
| 2186 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, NULL, FALSE)
; | |
| 2187 pDict->SetAt(FX_BSTRC("Contents"), pObj); | |
| 2188 m_Pos = dwSavePos; | |
| 2189 } | |
| 2190 if (pContext) { | |
| 2191 pContext->m_DictEnd = m_Pos; | |
| 2192 if (pContext->m_Flags & PDFPARSE_NOSTREAM) { | |
| 2193 return pDict; | |
| 2194 } | |
| 2195 } | |
| 2196 FX_FILESIZE SavedPos = m_Pos; | |
| 2197 FX_BOOL bIsNumber; | |
| 2198 CFX_ByteString nextword = GetNextWord(bIsNumber); | |
| 2199 if (nextword == FX_BSTRC("stream")) { | |
| 2200 CPDF_Stream* pStream = ReadStream(pDict, pContext, objnum, gennum); | |
| 2201 if (pStream) { | |
| 2202 return pStream; | |
| 2203 } | |
| 2204 if (pDict) | |
| 2205 pDict->Release(); | |
| 2206 return NULL; | |
| 2207 } else { | |
| 2208 m_Pos = SavedPos; | |
| 2209 return pDict; | |
| 2210 } | |
| 2211 } | |
| 2212 if (word == FX_BSTRC(">>")) { | |
| 2213 m_Pos = SavedPos; | |
| 2214 return NULL; | |
| 2215 } | |
| 2216 if (bTypeOnly) { | |
| 2217 return (CPDF_Object*)PDFOBJ_INVALID; | |
| 2218 } | |
| 2219 return NULL; | |
| 2220 } | |
| 2221 CPDF_Object* CPDF_SyntaxParser::GetObjectByStrict(CPDF_IndirectObjects* pObjList
, FX_DWORD objnum, FX_DWORD gennum, struct PARSE_CONTEXT* pContext) | |
| 2222 { | |
| 2223 CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth); | |
| 2224 if (++s_CurrentRecursionDepth > kParserMaxRecursionDepth) { | |
| 2225 return NULL; | |
| 2226 } | |
| 2227 FX_FILESIZE SavedPos = m_Pos; | |
| 2228 FX_BOOL bTypeOnly = pContext && (pContext->m_Flags & PDFPARSE_TYPEONLY); | |
| 2229 FX_BOOL bIsNumber; | |
| 2230 CFX_ByteString word = GetNextWord(bIsNumber); | |
| 2231 if (word.GetLength() == 0) { | |
| 2232 if (bTypeOnly) { | |
| 2233 return (CPDF_Object*)PDFOBJ_INVALID; | |
| 2234 } | |
| 2235 return NULL; | |
| 2236 } | |
| 2237 if (bIsNumber) { | |
| 2238 FX_FILESIZE SavedPos = m_Pos; | |
| 2239 CFX_ByteString nextword = GetNextWord(bIsNumber); | |
| 2240 if (bIsNumber) { | |
| 2241 CFX_ByteString nextword2 = GetNextWord(bIsNumber); | |
| 2242 if (nextword2 == FX_BSTRC("R")) { | |
| 2243 if (bTypeOnly) { | |
| 2244 return (CPDF_Object*)PDFOBJ_REFERENCE; | |
| 2245 } | |
| 2246 FX_DWORD objnum = FXSYS_atoi(word); | |
| 2247 return new CPDF_Reference(pObjList, objnum); | |
| 2248 } | |
| 2249 } | |
| 2250 m_Pos = SavedPos; | |
| 2251 if (bTypeOnly) { | |
| 2252 return (CPDF_Object*)PDFOBJ_NUMBER; | |
| 2253 } | |
| 2254 return CPDF_Number::Create(word); | |
| 2255 } | |
| 2256 if (word == FX_BSTRC("true") || word == FX_BSTRC("false")) { | |
| 2257 if (bTypeOnly) { | |
| 2258 return (CPDF_Object*)PDFOBJ_BOOLEAN; | |
| 2259 } | |
| 2260 return CPDF_Boolean::Create(word == FX_BSTRC("true")); | |
| 2261 } | |
| 2262 if (word == FX_BSTRC("null")) { | |
| 2263 if (bTypeOnly) { | |
| 2264 return (CPDF_Object*)PDFOBJ_NULL; | |
| 2265 } | |
| 2266 return CPDF_Null::Create(); | |
| 2267 } | |
| 2268 if (word == FX_BSTRC("(")) { | |
| 2269 if (bTypeOnly) { | |
| 2270 return (CPDF_Object*)PDFOBJ_STRING; | |
| 2271 } | |
| 2272 CFX_ByteString str = ReadString(); | |
| 2273 if (m_pCryptoHandler) { | |
| 2274 m_pCryptoHandler->Decrypt(objnum, gennum, str); | |
| 2275 } | |
| 2276 return CPDF_String::Create(str, FALSE); | |
| 2277 } | |
| 2278 if (word == FX_BSTRC("<")) { | |
| 2279 if (bTypeOnly) { | |
| 2280 return (CPDF_Object*)PDFOBJ_STRING; | |
| 2281 } | |
| 2282 CFX_ByteString str = ReadHexString(); | |
| 2283 if (m_pCryptoHandler) { | |
| 2284 m_pCryptoHandler->Decrypt(objnum, gennum, str); | |
| 2285 } | |
| 2286 return CPDF_String::Create(str, TRUE); | |
| 2287 } | |
| 2288 if (word == FX_BSTRC("[")) { | |
| 2289 if (bTypeOnly) { | |
| 2290 return (CPDF_Object*)PDFOBJ_ARRAY; | |
| 2291 } | |
| 2292 CPDF_Array* pArray = CPDF_Array::Create(); | |
| 2293 while (1) { | |
| 2294 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum); | |
| 2295 if (pObj == NULL) { | |
| 2296 if (m_WordBuffer[0] == ']') { | |
| 2297 return pArray; | |
| 2298 } | |
| 2299 if (pArray) { | |
| 2300 pArray->Release(); | |
| 2301 } | |
| 2302 return NULL; | |
| 2303 } | |
| 2304 pArray->Add(pObj); | |
| 2305 } | |
| 2306 } | |
| 2307 if (word[0] == '/') { | |
| 2308 if (bTypeOnly) { | |
| 2309 return (CPDF_Object*)PDFOBJ_NAME; | |
| 2310 } | |
| 2311 return CPDF_Name::Create(PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1
, m_WordSize - 1))); | |
| 2312 } | |
| 2313 if (word == FX_BSTRC("<<")) { | |
| 2314 if (bTypeOnly) { | |
| 2315 return (CPDF_Object*)PDFOBJ_DICTIONARY; | |
| 2316 } | |
| 2317 if (pContext) { | |
| 2318 pContext->m_DictStart = SavedPos; | |
| 2319 } | |
| 2320 CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); | |
| 2321 while (1) { | |
| 2322 FX_BOOL bIsNumber; | |
| 2323 FX_FILESIZE SavedPos = m_Pos; | |
| 2324 CFX_ByteString key = GetNextWord(bIsNumber); | |
| 2325 if (key.IsEmpty()) { | |
| 2326 if (pDict) { | |
| 2327 pDict->Release(); | |
| 2328 } | |
| 2329 return NULL; | |
| 2330 } | |
| 2331 if (key == FX_BSTRC(">>")) { | |
| 2332 break; | |
| 2333 } | |
| 2334 if (key == FX_BSTRC("endobj")) { | |
| 2335 m_Pos = SavedPos; | |
| 2336 break; | |
| 2337 } | |
| 2338 if (key[0] != '/') { | |
| 2339 continue; | |
| 2340 } | |
| 2341 key = PDF_NameDecode(key); | |
| 2342 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum); | |
| 2343 if (pObj == NULL) { | |
| 2344 if (pDict) { | |
| 2345 pDict->Release(); | |
| 2346 } | |
| 2347 uint8_t ch; | |
| 2348 while (1) { | |
| 2349 if (!GetNextChar(ch)) { | |
| 2350 break; | |
| 2351 } | |
| 2352 if (ch == 0x0A || ch == 0x0D) { | |
| 2353 break; | |
| 2354 } | |
| 2355 } | |
| 2356 return NULL; | |
| 2357 } | |
| 2358 if (key.GetLength() > 1) { | |
| 2359 pDict->AddValue(CFX_ByteStringC(key.c_str() + 1, key.GetLength()
- 1), pObj); | |
| 2360 } | |
| 2361 } | |
| 2362 if (pContext) { | |
| 2363 pContext->m_DictEnd = m_Pos; | |
| 2364 if (pContext->m_Flags & PDFPARSE_NOSTREAM) { | |
| 2365 return pDict; | |
| 2366 } | |
| 2367 } | |
| 2368 FX_FILESIZE SavedPos = m_Pos; | |
| 2369 FX_BOOL bIsNumber; | |
| 2370 CFX_ByteString nextword = GetNextWord(bIsNumber); | |
| 2371 if (nextword == FX_BSTRC("stream")) { | |
| 2372 CPDF_Stream* pStream = ReadStream(pDict, pContext, objnum, gennum); | |
| 2373 if (pStream) { | |
| 2374 return pStream; | |
| 2375 } | |
| 2376 if (pDict) { | |
| 2377 pDict->Release(); | |
| 2378 } | |
| 2379 return NULL; | |
| 2380 } else { | |
| 2381 m_Pos = SavedPos; | |
| 2382 return pDict; | |
| 2383 } | |
| 2384 } | |
| 2385 if (word == FX_BSTRC(">>")) { | |
| 2386 m_Pos = SavedPos; | |
| 2387 return NULL; | |
| 2388 } | |
| 2389 if (bTypeOnly) { | |
| 2390 return (CPDF_Object*)PDFOBJ_INVALID; | |
| 2391 } | |
| 2392 return NULL; | |
| 2393 } | |
| 2394 CPDF_Stream* CPDF_SyntaxParser::ReadStream(CPDF_Dictionary* pDict, PARSE_CONTEXT
* pContext, | |
| 2395 FX_DWORD objnum, FX_DWORD gennum) | |
| 2396 { | |
| 2397 CPDF_Object* pLenObj = pDict->GetElement(FX_BSTRC("Length")); | |
| 2398 FX_FILESIZE len = 0; | |
| 2399 if (pLenObj && ((pLenObj->GetType() != PDFOBJ_REFERENCE) || | |
| 2400 ((((CPDF_Reference*)pLenObj)->GetObjList() != NULL) && | |
| 2401 ((CPDF_Reference*)pLenObj)->GetRefObjNum() != objnum))) { | |
| 2402 len = pLenObj->GetInteger(); | |
| 2403 } | |
| 2404 | |
| 2405 ToNextLine(); | |
| 2406 FX_FILESIZE StreamStartPos = m_Pos; | |
| 2407 if (pContext) { | |
| 2408 pContext->m_DataStart = m_Pos; | |
| 2409 } | |
| 2410 | |
| 2411 CPDF_CryptoHandler* pCryptoHandler = objnum == (FX_DWORD)m_MetadataObjnum ?
NULL : m_pCryptoHandler; | |
| 2412 if (pCryptoHandler == NULL) { | |
| 2413 pdfium::base::CheckedNumeric<FX_FILESIZE> pos = m_Pos; | |
| 2414 pos += len; | |
| 2415 if (pos.IsValid() && pos.ValueOrDie() < m_FileLen) { | |
| 2416 m_Pos = pos.ValueOrDie(); | |
| 2417 } | |
| 2418 GetNextWord(); | |
| 2419 if (m_WordSize < 9 || FXSYS_memcmp(m_WordBuffer, "endstream", 9)) { | |
| 2420 m_Pos = StreamStartPos; | |
| 2421 FX_FILESIZE offset = FindTag(FX_BSTRC("endstream"), 0); | |
| 2422 if (offset >= 0) { | |
| 2423 FX_FILESIZE curPos = m_Pos; | |
| 2424 m_Pos = StreamStartPos; | |
| 2425 FX_FILESIZE endobjOffset = FindTag(FX_BSTRC("endobj"), 0); | |
| 2426 if (endobjOffset < offset && endobjOffset >= 0) { | |
| 2427 offset = endobjOffset; | |
| 2428 } else { | |
| 2429 m_Pos = curPos; | |
| 2430 } | |
| 2431 uint8_t byte1, byte2; | |
| 2432 GetCharAt(StreamStartPos + offset - 1, byte1); | |
| 2433 GetCharAt(StreamStartPos + offset - 2, byte2); | |
| 2434 if (byte1 == 0x0a && byte2 == 0x0d) { | |
| 2435 len -= 2; | |
| 2436 } else if (byte1 == 0x0a || byte1 == 0x0d) { | |
| 2437 len --; | |
| 2438 } | |
| 2439 len = (FX_DWORD)offset; | |
| 2440 pDict->SetAtInteger(FX_BSTRC("Length"), len); | |
| 2441 } else { | |
| 2442 m_Pos = StreamStartPos; | |
| 2443 if (FindTag(FX_BSTRC("endobj"), 0) < 0) { | |
| 2444 return NULL; | |
| 2445 } | |
| 2446 } | |
| 2447 } | |
| 2448 m_Pos = StreamStartPos; | |
| 2449 } | |
| 2450 CPDF_Stream* pStream; | |
| 2451 uint8_t* pData = FX_Alloc(uint8_t, len); | |
| 2452 ReadBlock(pData, len); | |
| 2453 if (pCryptoHandler) { | |
| 2454 CFX_BinaryBuf dest_buf; | |
| 2455 dest_buf.EstimateSize(pCryptoHandler->DecryptGetSize(len)); | |
| 2456 void* context = pCryptoHandler->DecryptStart(objnum, gennum); | |
| 2457 pCryptoHandler->DecryptStream(context, pData, len, dest_buf); | |
| 2458 pCryptoHandler->DecryptFinish(context, dest_buf); | |
| 2459 FX_Free(pData); | |
| 2460 pData = dest_buf.GetBuffer(); | |
| 2461 len = dest_buf.GetSize(); | |
| 2462 dest_buf.DetachBuffer(); | |
| 2463 } | |
| 2464 pStream = new CPDF_Stream(pData, len, pDict); | |
| 2465 if (pContext) { | |
| 2466 pContext->m_DataEnd = pContext->m_DataStart + len; | |
| 2467 } | |
| 2468 StreamStartPos = m_Pos; | |
| 2469 GetNextWord(); | |
| 2470 if (m_WordSize == 6 && 0 == FXSYS_memcmp(m_WordBuffer, "endobj", 6)) { | |
| 2471 m_Pos = StreamStartPos; | |
| 2472 } | |
| 2473 return pStream; | |
| 2474 } | |
| 2475 void CPDF_SyntaxParser::InitParser(IFX_FileRead* pFileAccess, FX_DWORD HeaderOff
set) | |
| 2476 { | |
| 2477 if (m_pFileBuf) { | |
| 2478 FX_Free(m_pFileBuf); | |
| 2479 m_pFileBuf = NULL; | |
| 2480 } | |
| 2481 m_pFileBuf = FX_Alloc(uint8_t, m_BufSize); | |
| 2482 m_HeaderOffset = HeaderOffset; | |
| 2483 m_FileLen = pFileAccess->GetSize(); | |
| 2484 m_Pos = 0; | |
| 2485 m_pFileAccess = pFileAccess; | |
| 2486 m_BufOffset = 0; | |
| 2487 pFileAccess->ReadBlock(m_pFileBuf, 0, (size_t)((FX_FILESIZE)m_BufSize > m_Fi
leLen ? m_FileLen : m_BufSize)); | |
| 2488 } | |
| 2489 int32_t CPDF_SyntaxParser::GetDirectNum() | |
| 2490 { | |
| 2491 GetNextWord(); | |
| 2492 if (!m_bIsNumber) { | |
| 2493 return 0; | |
| 2494 } | |
| 2495 m_WordBuffer[m_WordSize] = 0; | |
| 2496 return FXSYS_atoi((const FX_CHAR*)m_WordBuffer); | |
| 2497 } | |
| 2498 FX_BOOL CPDF_SyntaxParser::IsWholeWord(FX_FILESIZE startpos, FX_FILESIZE limit,
const uint8_t* tag, FX_DWORD taglen) | |
| 2499 { | |
| 2500 uint8_t type = PDF_CharType[tag[0]]; | |
| 2501 FX_BOOL bCheckLeft = type != 'D' && type != 'W'; | |
| 2502 type = PDF_CharType[tag[taglen - 1]]; | |
| 2503 FX_BOOL bCheckRight = type != 'D' && type != 'W'; | |
| 2504 uint8_t ch; | |
| 2505 if (bCheckRight && startpos + (int32_t)taglen <= limit && GetCharAt(startpos
+ (int32_t)taglen, ch)) { | |
| 2506 uint8_t type = PDF_CharType[ch]; | |
| 2507 if (type == 'N' || type == 'R') { | |
| 2508 return FALSE; | |
| 2509 } | |
| 2510 } | |
| 2511 if (bCheckLeft && startpos > 0 && GetCharAt(startpos - 1, ch)) { | |
| 2512 uint8_t type = PDF_CharType[ch]; | |
| 2513 if (type == 'N' || type == 'R') { | |
| 2514 return FALSE; | |
| 2515 } | |
| 2516 } | |
| 2517 return TRUE; | |
| 2518 } | |
| 2519 FX_BOOL CPDF_SyntaxParser::SearchWord(const CFX_ByteStringC& tag, FX_BOOL bWhole
Word, FX_BOOL bForward, FX_FILESIZE limit) | |
| 2520 { | |
| 2521 int32_t taglen = tag.GetLength(); | |
| 2522 if (taglen == 0) { | |
| 2523 return FALSE; | |
| 2524 } | |
| 2525 FX_FILESIZE pos = m_Pos; | |
| 2526 int32_t offset = 0; | |
| 2527 if (!bForward) { | |
| 2528 offset = taglen - 1; | |
| 2529 } | |
| 2530 const uint8_t* tag_data = tag.GetPtr(); | |
| 2531 uint8_t byte; | |
| 2532 while (1) { | |
| 2533 if (bForward) { | |
| 2534 if (limit) { | |
| 2535 if (pos >= m_Pos + limit) { | |
| 2536 return FALSE; | |
| 2537 } | |
| 2538 } | |
| 2539 if (!GetCharAt(pos, byte)) { | |
| 2540 return FALSE; | |
| 2541 } | |
| 2542 } else { | |
| 2543 if (limit) { | |
| 2544 if (pos <= m_Pos - limit) { | |
| 2545 return FALSE; | |
| 2546 } | |
| 2547 } | |
| 2548 if (!GetCharAtBackward(pos, byte)) { | |
| 2549 return FALSE; | |
| 2550 } | |
| 2551 } | |
| 2552 if (byte == tag_data[offset]) { | |
| 2553 if (bForward) { | |
| 2554 offset ++; | |
| 2555 if (offset < taglen) { | |
| 2556 pos ++; | |
| 2557 continue; | |
| 2558 } | |
| 2559 } else { | |
| 2560 offset --; | |
| 2561 if (offset >= 0) { | |
| 2562 pos --; | |
| 2563 continue; | |
| 2564 } | |
| 2565 } | |
| 2566 FX_FILESIZE startpos = bForward ? pos - taglen + 1 : pos; | |
| 2567 if (!bWholeWord || IsWholeWord(startpos, limit, tag.GetPtr(), taglen
)) { | |
| 2568 m_Pos = startpos; | |
| 2569 return TRUE; | |
| 2570 } | |
| 2571 } | |
| 2572 if (bForward) { | |
| 2573 offset = byte == tag_data[0] ? 1 : 0; | |
| 2574 pos ++; | |
| 2575 } else { | |
| 2576 offset = byte == tag_data[taglen - 1] ? taglen - 2 : taglen - 1; | |
| 2577 pos --; | |
| 2578 } | |
| 2579 if (pos < 0) { | |
| 2580 return FALSE; | |
| 2581 } | |
| 2582 } | |
| 2583 return FALSE; | |
| 2584 } | |
| 2585 struct _SearchTagRecord { | |
| 2586 const uint8_t* m_pTag; | |
| 2587 FX_DWORD m_Len; | |
| 2588 FX_DWORD m_Offset; | |
| 2589 }; | 2954 }; |
| 2590 int32_t CPDF_SyntaxParser::SearchMultiWord(const CFX_ByteStringC& tags, FX_BOOL
bWholeWord, FX_FILESIZE limit) | 2955 |
| 2591 { | 2956 IPDF_DataAvail::IPDF_DataAvail(IFX_FileAvail* pFileAvail, |
| 2592 int32_t ntags = 1, i; | 2957 IFX_FileRead* pFileRead) |
| 2593 for (i = 0; i < tags.GetLength(); i ++) | 2958 : m_pFileAvail(pFileAvail), m_pFileRead(pFileRead) {} |
| 2594 if (tags[i] == 0) { | |
| 2595 ntags ++; | |
| 2596 } | |
| 2597 _SearchTagRecord* pPatterns = FX_Alloc(_SearchTagRecord, ntags); | |
| 2598 FX_DWORD start = 0, itag = 0, max_len = 0; | |
| 2599 for (i = 0; i <= tags.GetLength(); i ++) { | |
| 2600 if (tags[i] == 0) { | |
| 2601 FX_DWORD len = i - start; | |
| 2602 if (len > max_len) { | |
| 2603 max_len = len; | |
| 2604 } | |
| 2605 pPatterns[itag].m_pTag = tags.GetPtr() + start; | |
| 2606 pPatterns[itag].m_Len = len; | |
| 2607 pPatterns[itag].m_Offset = 0; | |
| 2608 start = i + 1; | |
| 2609 itag ++; | |
| 2610 } | |
| 2611 } | |
| 2612 FX_FILESIZE pos = m_Pos; | |
| 2613 uint8_t byte; | |
| 2614 GetCharAt(pos++, byte); | |
| 2615 int32_t found = -1; | |
| 2616 while (1) { | |
| 2617 for (i = 0; i < ntags; i ++) { | |
| 2618 if (pPatterns[i].m_pTag[pPatterns[i].m_Offset] == byte) { | |
| 2619 pPatterns[i].m_Offset ++; | |
| 2620 if (pPatterns[i].m_Offset == pPatterns[i].m_Len) { | |
| 2621 if (!bWholeWord || IsWholeWord(pos - pPatterns[i].m_Len, lim
it, pPatterns[i].m_pTag, pPatterns[i].m_Len)) { | |
| 2622 found = i; | |
| 2623 goto end; | |
| 2624 } else { | |
| 2625 if (pPatterns[i].m_pTag[0] == byte) { | |
| 2626 pPatterns[i].m_Offset = 1; | |
| 2627 } else { | |
| 2628 pPatterns[i].m_Offset = 0; | |
| 2629 } | |
| 2630 } | |
| 2631 } | |
| 2632 } else { | |
| 2633 if (pPatterns[i].m_pTag[0] == byte) { | |
| 2634 pPatterns[i].m_Offset = 1; | |
| 2635 } else { | |
| 2636 pPatterns[i].m_Offset = 0; | |
| 2637 } | |
| 2638 } | |
| 2639 } | |
| 2640 if (limit && pos >= m_Pos + limit) { | |
| 2641 goto end; | |
| 2642 } | |
| 2643 if (!GetCharAt(pos, byte)) { | |
| 2644 goto end; | |
| 2645 } | |
| 2646 pos ++; | |
| 2647 } | |
| 2648 end: | |
| 2649 FX_Free(pPatterns); | |
| 2650 return found; | |
| 2651 } | |
| 2652 FX_FILESIZE CPDF_SyntaxParser::FindTag(const CFX_ByteStringC& tag, FX_FILESIZE l
imit) | |
| 2653 { | |
| 2654 int32_t taglen = tag.GetLength(); | |
| 2655 int32_t match = 0; | |
| 2656 limit += m_Pos; | |
| 2657 FX_FILESIZE startpos = m_Pos; | |
| 2658 while (1) { | |
| 2659 uint8_t ch; | |
| 2660 if (!GetNextChar(ch)) { | |
| 2661 return -1; | |
| 2662 } | |
| 2663 if (ch == tag[match]) { | |
| 2664 match ++; | |
| 2665 if (match == taglen) { | |
| 2666 return m_Pos - startpos - taglen; | |
| 2667 } | |
| 2668 } else { | |
| 2669 match = ch == tag[0] ? 1 : 0; | |
| 2670 } | |
| 2671 if (limit && m_Pos == limit) { | |
| 2672 return -1; | |
| 2673 } | |
| 2674 } | |
| 2675 return -1; | |
| 2676 } | |
| 2677 void CPDF_SyntaxParser::GetBinary(uint8_t* buffer, FX_DWORD size) | |
| 2678 { | |
| 2679 FX_DWORD offset = 0; | |
| 2680 uint8_t ch; | |
| 2681 while (1) { | |
| 2682 if (!GetNextChar(ch)) { | |
| 2683 return; | |
| 2684 } | |
| 2685 buffer[offset++] = ch; | |
| 2686 if (offset == size) { | |
| 2687 break; | |
| 2688 } | |
| 2689 } | |
| 2690 } | |
| 2691 | |
| 2692 class CPDF_DataAvail final : public IPDF_DataAvail | |
| 2693 { | |
| 2694 public: | |
| 2695 CPDF_DataAvail(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRead); | |
| 2696 ~CPDF_DataAvail(); | |
| 2697 | |
| 2698 virtual FX_BOOL IsDocAvail(IFX_DownloadHints* pHints) o
verride; | |
| 2699 | |
| 2700 virtual void SetDocument(CPDF_Document* pDoc) overri
de; | |
| 2701 | |
| 2702 virtual FX_BOOL IsPageAvail(int iPage, IFX_DownloadHints
* pHints) override; | |
| 2703 | |
| 2704 virtual int32_t IsFormAvail(IFX_DownloadHints *pHints)
override; | |
| 2705 | |
| 2706 virtual int32_t IsLinearizedPDF() override; | |
| 2707 | |
| 2708 virtual FX_BOOL IsLinearized() override | |
| 2709 { | |
| 2710 return m_bLinearized; | |
| 2711 } | |
| 2712 | |
| 2713 virtual void GetLinearizedMainXRefInfo(FX_FILESIZE *p
Pos, FX_DWORD *pSize) override; | |
| 2714 | |
| 2715 protected: | |
| 2716 static const int kMaxDataAvailRecursionDepth = 64; | |
| 2717 static int s_CurrentDataAvailRecursionDepth; | |
| 2718 | |
| 2719 FX_DWORD GetObjectSize(FX_DWORD objnum, FX_FILESI
ZE& offset); | |
| 2720 FX_BOOL IsObjectsAvail(CFX_PtrArray& obj_array,
FX_BOOL bParsePage, IFX_DownloadHints* pHints, CFX_PtrArray &ret_array); | |
| 2721 FX_BOOL CheckDocStatus(IFX_DownloadHints *pHints
); | |
| 2722 FX_BOOL CheckHeader(IFX_DownloadHints* pHints); | |
| 2723 FX_BOOL CheckFirstPage(IFX_DownloadHints *pHints
); | |
| 2724 FX_BOOL CheckEnd(IFX_DownloadHints *pHints); | |
| 2725 FX_BOOL CheckCrossRef(IFX_DownloadHints* pHints)
; | |
| 2726 FX_BOOL CheckCrossRefItem(IFX_DownloadHints *pHi
nts); | |
| 2727 FX_BOOL CheckTrailer(IFX_DownloadHints* pHints); | |
| 2728 FX_BOOL CheckRoot(IFX_DownloadHints* pHints); | |
| 2729 FX_BOOL CheckInfo(IFX_DownloadHints* pHints); | |
| 2730 FX_BOOL CheckPages(IFX_DownloadHints* pHints); | |
| 2731 FX_BOOL CheckPage(IFX_DownloadHints* pHints); | |
| 2732 FX_BOOL CheckResources(IFX_DownloadHints* pHints
); | |
| 2733 FX_BOOL CheckAnnots(IFX_DownloadHints* pHints); | |
| 2734 FX_BOOL CheckAcroForm(IFX_DownloadHints* pHints)
; | |
| 2735 FX_BOOL CheckAcroFormSubObject(IFX_DownloadHints
* pHints); | |
| 2736 FX_BOOL CheckTrailerAppend(IFX_DownloadHints* pH
ints); | |
| 2737 FX_BOOL CheckPageStatus(IFX_DownloadHints* pHint
s); | |
| 2738 FX_BOOL CheckAllCrossRefStream(IFX_DownloadHints
*pHints); | |
| 2739 | |
| 2740 int32_t CheckCrossRefStream(IFX_DownloadHints *pH
ints, FX_FILESIZE &xref_offset); | |
| 2741 FX_BOOL IsLinearizedFile(uint8_t* pData, FX_DWOR
D dwLen); | |
| 2742 void SetStartOffset(FX_FILESIZE dwOffset); | |
| 2743 FX_BOOL GetNextToken(CFX_ByteString &token); | |
| 2744 FX_BOOL GetNextChar(uint8_t &ch); | |
| 2745 CPDF_Object * ParseIndirectObjectAt(FX_FILESIZE pos, F
X_DWORD objnum); | |
| 2746 CPDF_Object * GetObject(FX_DWORD objnum, IFX_DownloadH
ints* pHints, FX_BOOL *pExistInFile); | |
| 2747 FX_BOOL GetPageKids(CPDF_Parser *pParser, CPDF_O
bject *pPages); | |
| 2748 FX_BOOL PreparePageItem(); | |
| 2749 FX_BOOL LoadPages(IFX_DownloadHints* pHints); | |
| 2750 FX_BOOL LoadAllXref(IFX_DownloadHints* pHints); | |
| 2751 FX_BOOL LoadAllFile(IFX_DownloadHints* pHints); | |
| 2752 FX_BOOL CheckLinearizedData(IFX_DownloadHints* p
Hints); | |
| 2753 FX_BOOL CheckFileResources(IFX_DownloadHints* pH
ints); | |
| 2754 FX_BOOL CheckPageAnnots(int iPage, IFX_DownloadH
ints* pHints); | |
| 2755 | |
| 2756 FX_BOOL CheckLinearizedFirstPage(int iPage, IFX_
DownloadHints* pHints); | |
| 2757 FX_BOOL HaveResourceAncestor(CPDF_Dictionary *pD
ict); | |
| 2758 FX_BOOL CheckPage(int32_t iPage, IFX_DownloadHin
ts* pHints); | |
| 2759 FX_BOOL LoadDocPages(IFX_DownloadHints* pHints); | |
| 2760 FX_BOOL LoadDocPage(int32_t iPage, IFX_DownloadH
ints* pHints); | |
| 2761 FX_BOOL CheckPageNode(CPDF_PageNode &pageNodes,
int32_t iPage, int32_t &iCount, IFX_DownloadHints* pHints); | |
| 2762 FX_BOOL CheckUnkownPageNode(FX_DWORD dwPageNo, C
PDF_PageNode *pPageNode, IFX_DownloadHints* pHints); | |
| 2763 FX_BOOL CheckArrayPageNode(FX_DWORD dwPageNo, CP
DF_PageNode *pPageNode, IFX_DownloadHints* pHints); | |
| 2764 FX_BOOL CheckPageCount(IFX_DownloadHints* pHints
); | |
| 2765 FX_BOOL IsFirstCheck(int iPage); | |
| 2766 void ResetFirstCheck(int iPage); | |
| 2767 | |
| 2768 CPDF_Parser m_parser; | |
| 2769 | |
| 2770 CPDF_SyntaxParser m_syntaxParser; | |
| 2771 | |
| 2772 CPDF_Object *m_pRoot; | |
| 2773 | |
| 2774 FX_DWORD m_dwRootObjNum; | |
| 2775 | |
| 2776 FX_DWORD m_dwInfoObjNum; | |
| 2777 | |
| 2778 CPDF_Object *m_pLinearized; | |
| 2779 | |
| 2780 CPDF_Object *m_pTrailer; | |
| 2781 | |
| 2782 FX_BOOL m_bDocAvail; | |
| 2783 | |
| 2784 FX_FILESIZE m_dwHeaderOffset; | |
| 2785 | |
| 2786 FX_FILESIZE m_dwLastXRefOffset; | |
| 2787 | |
| 2788 FX_FILESIZE m_dwXRefOffset; | |
| 2789 | |
| 2790 FX_FILESIZE m_dwTrailerOffset; | |
| 2791 | |
| 2792 FX_FILESIZE m_dwCurrentOffset; | |
| 2793 | |
| 2794 PDF_DATAAVAIL_STATUS m_docStatus; | |
| 2795 | |
| 2796 FX_FILESIZE m_dwFileLen; | |
| 2797 | |
| 2798 CPDF_Document* m_pDocument; | |
| 2799 | |
| 2800 CPDF_SortObjNumArray m_objnum_array; | |
| 2801 | |
| 2802 CFX_PtrArray m_objs_array; | |
| 2803 | |
| 2804 FX_FILESIZE m_Pos; | |
| 2805 | |
| 2806 FX_FILESIZE m_bufferOffset; | |
| 2807 | |
| 2808 FX_DWORD m_bufferSize; | |
| 2809 | |
| 2810 CFX_ByteString m_WordBuf; | |
| 2811 | |
| 2812 uint8_t m_WordBuffer[257]; | |
| 2813 | |
| 2814 FX_DWORD m_WordSize; | |
| 2815 | |
| 2816 uint8_t m_bufferData[512]; | |
| 2817 | |
| 2818 CFX_FileSizeArray m_CrossOffset; | |
| 2819 | |
| 2820 CFX_DWordArray m_XRefStreamList; | |
| 2821 | |
| 2822 CFX_DWordArray m_PageObjList; | |
| 2823 | |
| 2824 FX_DWORD m_PagesObjNum; | |
| 2825 | |
| 2826 FX_BOOL m_bLinearized; | |
| 2827 | |
| 2828 FX_DWORD m_dwFirstPageNo; | |
| 2829 | |
| 2830 FX_BOOL m_bLinearedDataOK; | |
| 2831 | |
| 2832 FX_BOOL m_bMainXRefLoadTried; | |
| 2833 | |
| 2834 FX_BOOL m_bMainXRefLoadedOK; | |
| 2835 | |
| 2836 FX_BOOL m_bPagesTreeLoad; | |
| 2837 | |
| 2838 FX_BOOL m_bPagesLoad; | |
| 2839 | |
| 2840 CPDF_Parser * m_pCurrentParser; | |
| 2841 | |
| 2842 FX_FILESIZE m_dwCurrentXRefSteam; | |
| 2843 | |
| 2844 FX_BOOL m_bAnnotsLoad; | |
| 2845 | |
| 2846 FX_BOOL m_bHaveAcroForm; | |
| 2847 | |
| 2848 FX_DWORD m_dwAcroFormObjNum; | |
| 2849 | |
| 2850 FX_BOOL m_bAcroFormLoad; | |
| 2851 | |
| 2852 CPDF_Object * m_pAcroForm; | |
| 2853 | |
| 2854 CFX_PtrArray m_arrayAcroforms; | |
| 2855 | |
| 2856 CPDF_Dictionary * m_pPageDict; | |
| 2857 | |
| 2858 CPDF_Object * m_pPageResource; | |
| 2859 | |
| 2860 FX_BOOL m_bNeedDownLoadResource; | |
| 2861 | |
| 2862 FX_BOOL m_bPageLoadedOK; | |
| 2863 | |
| 2864 FX_BOOL m_bLinearizedFormParamLoad; | |
| 2865 | |
| 2866 CFX_PtrArray m_PagesArray; | |
| 2867 | |
| 2868 FX_DWORD m_dwEncryptObjNum; | |
| 2869 | |
| 2870 FX_FILESIZE m_dwPrevXRefOffset; | |
| 2871 | |
| 2872 FX_BOOL m_bTotalLoadPageTree; | |
| 2873 | |
| 2874 FX_BOOL m_bCurPageDictLoadOK; | |
| 2875 | |
| 2876 CPDF_PageNode m_pageNodes; | |
| 2877 | |
| 2878 CFX_CMapDWordToDWord * m_pageMapCheckState; | |
| 2879 | |
| 2880 CFX_CMapDWordToDWord * m_pagesLoadState; | |
| 2881 }; | |
| 2882 | |
| 2883 IPDF_DataAvail::IPDF_DataAvail(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRea
d) : | |
| 2884 m_pFileAvail(pFileAvail), | |
| 2885 m_pFileRead(pFileRead) { | |
| 2886 } | |
| 2887 | 2959 |
| 2888 // static | 2960 // static |
| 2889 IPDF_DataAvail* IPDF_DataAvail::Create(IFX_FileAvail* pFileAvail, IFX_FileRead*
pFileRead) | 2961 IPDF_DataAvail* IPDF_DataAvail::Create(IFX_FileAvail* pFileAvail, |
| 2890 { | 2962 IFX_FileRead* pFileRead) { |
| 2891 return new CPDF_DataAvail(pFileAvail, pFileRead); | 2963 return new CPDF_DataAvail(pFileAvail, pFileRead); |
| 2892 } | 2964 } |
| 2893 | 2965 |
| 2894 // static | 2966 // static |
| 2895 int CPDF_DataAvail::s_CurrentDataAvailRecursionDepth = 0; | 2967 int CPDF_DataAvail::s_CurrentDataAvailRecursionDepth = 0; |
| 2896 | 2968 |
| 2897 CPDF_DataAvail::CPDF_DataAvail(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRea
d) | 2969 CPDF_DataAvail::CPDF_DataAvail(IFX_FileAvail* pFileAvail, |
| 2898 : IPDF_DataAvail(pFileAvail, pFileRead) | 2970 IFX_FileRead* pFileRead) |
| 2899 { | 2971 : IPDF_DataAvail(pFileAvail, pFileRead) { |
| 2900 m_Pos = 0; | 2972 m_Pos = 0; |
| 2901 m_dwFileLen = 0; | 2973 m_dwFileLen = 0; |
| 2902 if (m_pFileRead) { | 2974 if (m_pFileRead) { |
| 2903 m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize(); | 2975 m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize(); |
| 2904 } | 2976 } |
| 2905 m_dwCurrentOffset = 0; | 2977 m_dwCurrentOffset = 0; |
| 2906 m_WordSize = 0; | 2978 m_WordSize = 0; |
| 2907 m_dwXRefOffset = 0; | 2979 m_dwXRefOffset = 0; |
| 2908 m_bufferOffset = 0; | 2980 m_bufferOffset = 0; |
| 2909 m_dwFirstPageNo = 0; | 2981 m_dwFirstPageNo = 0; |
| 2910 m_bufferSize = 0; | 2982 m_bufferSize = 0; |
| 2911 m_PagesObjNum = 0; | 2983 m_PagesObjNum = 0; |
| 2912 m_dwCurrentXRefSteam = 0; | 2984 m_dwCurrentXRefSteam = 0; |
| 2913 m_dwAcroFormObjNum = 0; | 2985 m_dwAcroFormObjNum = 0; |
| 2914 m_dwInfoObjNum = 0; | 2986 m_dwInfoObjNum = 0; |
| 2915 m_pDocument = 0; | 2987 m_pDocument = 0; |
| 2916 m_dwEncryptObjNum = 0; | 2988 m_dwEncryptObjNum = 0; |
| 2917 m_dwPrevXRefOffset = 0; | 2989 m_dwPrevXRefOffset = 0; |
| 2918 m_dwLastXRefOffset = 0; | 2990 m_dwLastXRefOffset = 0; |
| 2919 m_bDocAvail = FALSE; | 2991 m_bDocAvail = FALSE; |
| 2920 m_bMainXRefLoadTried = FALSE; | 2992 m_bMainXRefLoadTried = FALSE; |
| 2921 m_bDocAvail = FALSE; | 2993 m_bDocAvail = FALSE; |
| 2922 m_bLinearized = FALSE; | 2994 m_bLinearized = FALSE; |
| 2923 m_bPagesLoad = FALSE; | 2995 m_bPagesLoad = FALSE; |
| 2924 m_bPagesTreeLoad = FALSE; | 2996 m_bPagesTreeLoad = FALSE; |
| 2925 m_bMainXRefLoadedOK = FALSE; | 2997 m_bMainXRefLoadedOK = FALSE; |
| 2926 m_bAnnotsLoad = FALSE; | 2998 m_bAnnotsLoad = FALSE; |
| 2927 m_bHaveAcroForm = FALSE; | 2999 m_bHaveAcroForm = FALSE; |
| 2928 m_bAcroFormLoad = FALSE; | 3000 m_bAcroFormLoad = FALSE; |
| 2929 m_bPageLoadedOK = FALSE; | 3001 m_bPageLoadedOK = FALSE; |
| 2930 m_bNeedDownLoadResource = FALSE; | 3002 m_bNeedDownLoadResource = FALSE; |
| 2931 m_bLinearizedFormParamLoad = FALSE; | 3003 m_bLinearizedFormParamLoad = FALSE; |
| 2932 m_pLinearized = NULL; | 3004 m_pLinearized = NULL; |
| 2933 m_pRoot = NULL; | 3005 m_pRoot = NULL; |
| 2934 m_pTrailer = NULL; | 3006 m_pTrailer = NULL; |
| 2935 m_pCurrentParser = NULL; | 3007 m_pCurrentParser = NULL; |
| 2936 m_pAcroForm = NULL; | 3008 m_pAcroForm = NULL; |
| 2937 m_pPageDict = NULL; | 3009 m_pPageDict = NULL; |
| 2938 m_pPageResource = NULL; | 3010 m_pPageResource = NULL; |
| 2939 m_pageMapCheckState = NULL; | 3011 m_pageMapCheckState = NULL; |
| 2940 m_docStatus = PDF_DATAAVAIL_HEADER; | 3012 m_docStatus = PDF_DATAAVAIL_HEADER; |
| 2941 m_parser.m_bOwnFileRead = FALSE; | 3013 m_parser.m_bOwnFileRead = FALSE; |
| 2942 m_bTotalLoadPageTree = FALSE; | 3014 m_bTotalLoadPageTree = FALSE; |
| 2943 m_bCurPageDictLoadOK = FALSE; | 3015 m_bCurPageDictLoadOK = FALSE; |
| 2944 m_bLinearedDataOK = FALSE; | 3016 m_bLinearedDataOK = FALSE; |
| 2945 m_pagesLoadState = NULL; | 3017 m_pagesLoadState = NULL; |
| 2946 } | 3018 } |
| 2947 CPDF_DataAvail::~CPDF_DataAvail() | 3019 CPDF_DataAvail::~CPDF_DataAvail() { |
| 2948 { | 3020 if (m_pLinearized) { |
| 2949 if (m_pLinearized)» { | 3021 m_pLinearized->Release(); |
| 2950 m_pLinearized->Release(); | 3022 } |
| 2951 } | 3023 if (m_pRoot) { |
| 2952 if (m_pRoot) { | 3024 m_pRoot->Release(); |
| 2953 m_pRoot->Release(); | 3025 } |
| 2954 } | 3026 if (m_pTrailer) { |
| 2955 if (m_pTrailer) { | 3027 m_pTrailer->Release(); |
| 2956 m_pTrailer->Release(); | 3028 } |
| 2957 } | 3029 delete m_pageMapCheckState; |
| 2958 delete m_pageMapCheckState; | 3030 delete m_pagesLoadState; |
| 2959 delete m_pagesLoadState; | 3031 int32_t i = 0; |
| 2960 int32_t i = 0; | 3032 int32_t iSize = m_arrayAcroforms.GetSize(); |
| 3033 for (i = 0; i < iSize; ++i) { |
| 3034 ((CPDF_Object*)m_arrayAcroforms.GetAt(i))->Release(); |
| 3035 } |
| 3036 } |
| 3037 void CPDF_DataAvail::SetDocument(CPDF_Document* pDoc) { |
| 3038 m_pDocument = pDoc; |
| 3039 } |
| 3040 FX_DWORD CPDF_DataAvail::GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset) { |
| 3041 CPDF_Parser* pParser = (CPDF_Parser*)(m_pDocument->GetParser()); |
| 3042 if (pParser == NULL) { |
| 3043 return 0; |
| 3044 } |
| 3045 if (objnum >= (FX_DWORD)pParser->m_CrossRef.GetSize()) { |
| 3046 return 0; |
| 3047 } |
| 3048 if (pParser->m_V5Type[objnum] == 2) { |
| 3049 objnum = (FX_DWORD)pParser->m_CrossRef[objnum]; |
| 3050 } |
| 3051 if (pParser->m_V5Type[objnum] == 1 || pParser->m_V5Type[objnum] == 255) { |
| 3052 offset = pParser->m_CrossRef[objnum]; |
| 3053 if (offset == 0) { |
| 3054 return 0; |
| 3055 } |
| 3056 void* pResult = FXSYS_bsearch(&offset, pParser->m_SortedOffset.GetData(), |
| 3057 pParser->m_SortedOffset.GetSize(), |
| 3058 sizeof(FX_FILESIZE), _CompareFileSize); |
| 3059 if (pResult == NULL) { |
| 3060 return 0; |
| 3061 } |
| 3062 if ((FX_FILESIZE*)pResult - |
| 3063 (FX_FILESIZE*)pParser->m_SortedOffset.GetData() == |
| 3064 pParser->m_SortedOffset.GetSize() - 1) { |
| 3065 return 0; |
| 3066 } |
| 3067 return (FX_DWORD)(((FX_FILESIZE*)pResult)[1] - offset); |
| 3068 } |
| 3069 return 0; |
| 3070 } |
| 3071 FX_BOOL CPDF_DataAvail::IsObjectsAvail(CFX_PtrArray& obj_array, |
| 3072 FX_BOOL bParsePage, |
| 3073 IFX_DownloadHints* pHints, |
| 3074 CFX_PtrArray& ret_array) { |
| 3075 if (!obj_array.GetSize()) { |
| 3076 return TRUE; |
| 3077 } |
| 3078 FX_DWORD count = 0; |
| 3079 CFX_PtrArray new_obj_array; |
| 3080 int32_t i = 0; |
| 3081 for (i = 0; i < obj_array.GetSize(); i++) { |
| 3082 CPDF_Object* pObj = (CPDF_Object*)obj_array[i]; |
| 3083 if (!pObj) { |
| 3084 continue; |
| 3085 } |
| 3086 int32_t type = pObj->GetType(); |
| 3087 switch (type) { |
| 3088 case PDFOBJ_ARRAY: { |
| 3089 CPDF_Array* pArray = pObj->GetArray(); |
| 3090 for (FX_DWORD k = 0; k < pArray->GetCount(); k++) { |
| 3091 new_obj_array.Add(pArray->GetElement(k)); |
| 3092 } |
| 3093 } break; |
| 3094 case PDFOBJ_STREAM: |
| 3095 pObj = pObj->GetDict(); |
| 3096 case PDFOBJ_DICTIONARY: { |
| 3097 CPDF_Dictionary* pDict = pObj->GetDict(); |
| 3098 if (pDict && pDict->GetString("Type") == "Page" && !bParsePage) { |
| 3099 continue; |
| 3100 } |
| 3101 FX_POSITION pos = pDict->GetStartPos(); |
| 3102 while (pos) { |
| 3103 CPDF_Object* value; |
| 3104 CFX_ByteString key; |
| 3105 value = pDict->GetNextElement(pos, key); |
| 3106 if (key != "Parent") { |
| 3107 new_obj_array.Add(value); |
| 3108 } |
| 3109 } |
| 3110 } break; |
| 3111 case PDFOBJ_REFERENCE: { |
| 3112 CPDF_Reference* pRef = (CPDF_Reference*)pObj; |
| 3113 FX_DWORD dwNum = pRef->GetRefObjNum(); |
| 3114 FX_FILESIZE offset; |
| 3115 FX_DWORD original_size = GetObjectSize(dwNum, offset); |
| 3116 pdfium::base::CheckedNumeric<FX_DWORD> size = original_size; |
| 3117 if (size.ValueOrDefault(0) == 0 || offset < 0 || |
| 3118 offset >= m_dwFileLen) { |
| 3119 break; |
| 3120 } |
| 3121 |
| 3122 size += offset; |
| 3123 size += 512; |
| 3124 if (!size.IsValid()) { |
| 3125 break; |
| 3126 } |
| 3127 if (size.ValueOrDie() > m_dwFileLen) { |
| 3128 size = m_dwFileLen - offset; |
| 3129 } else { |
| 3130 size = original_size + 512; |
| 3131 } |
| 3132 if (!size.IsValid()) { |
| 3133 break; |
| 3134 } |
| 3135 if (!m_pFileAvail->IsDataAvail(offset, size.ValueOrDie())) { |
| 3136 pHints->AddSegment(offset, size.ValueOrDie()); |
| 3137 ret_array.Add(pObj); |
| 3138 count++; |
| 3139 } else if (!m_objnum_array.Find(dwNum)) { |
| 3140 m_objnum_array.AddObjNum(dwNum); |
| 3141 CPDF_Object* pReferred = |
| 3142 m_pDocument->GetIndirectObject(pRef->GetRefObjNum(), NULL); |
| 3143 if (pReferred) { |
| 3144 new_obj_array.Add(pReferred); |
| 3145 } |
| 3146 } |
| 3147 } break; |
| 3148 } |
| 3149 } |
| 3150 if (count > 0) { |
| 3151 int32_t iSize = new_obj_array.GetSize(); |
| 3152 for (i = 0; i < iSize; ++i) { |
| 3153 CPDF_Object* pObj = (CPDF_Object*)new_obj_array[i]; |
| 3154 int32_t type = pObj->GetType(); |
| 3155 if (type == PDFOBJ_REFERENCE) { |
| 3156 CPDF_Reference* pRef = (CPDF_Reference*)pObj; |
| 3157 FX_DWORD dwNum = pRef->GetRefObjNum(); |
| 3158 if (!m_objnum_array.Find(dwNum)) { |
| 3159 ret_array.Add(pObj); |
| 3160 } |
| 3161 } else { |
| 3162 ret_array.Add(pObj); |
| 3163 } |
| 3164 } |
| 3165 return FALSE; |
| 3166 } |
| 3167 obj_array.RemoveAll(); |
| 3168 obj_array.Append(new_obj_array); |
| 3169 return IsObjectsAvail(obj_array, FALSE, pHints, ret_array); |
| 3170 } |
| 3171 FX_BOOL CPDF_DataAvail::IsDocAvail(IFX_DownloadHints* pHints) { |
| 3172 if (!m_dwFileLen && m_pFileRead) { |
| 3173 m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize(); |
| 3174 if (!m_dwFileLen) { |
| 3175 return TRUE; |
| 3176 } |
| 3177 } |
| 3178 while (!m_bDocAvail) { |
| 3179 if (!CheckDocStatus(pHints)) { |
| 3180 return FALSE; |
| 3181 } |
| 3182 } |
| 3183 return TRUE; |
| 3184 } |
| 3185 FX_BOOL CPDF_DataAvail::CheckAcroFormSubObject(IFX_DownloadHints* pHints) { |
| 3186 if (!m_objs_array.GetSize()) { |
| 3187 m_objs_array.RemoveAll(); |
| 3188 m_objnum_array.RemoveAll(); |
| 3189 CFX_PtrArray obj_array; |
| 3190 obj_array.Append(m_arrayAcroforms); |
| 3191 FX_BOOL bRet = IsObjectsAvail(obj_array, FALSE, pHints, m_objs_array); |
| 3192 if (bRet) { |
| 3193 m_objs_array.RemoveAll(); |
| 3194 } |
| 3195 return bRet; |
| 3196 } |
| 3197 CFX_PtrArray new_objs_array; |
| 3198 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); |
| 3199 if (bRet) { |
| 2961 int32_t iSize = m_arrayAcroforms.GetSize(); | 3200 int32_t iSize = m_arrayAcroforms.GetSize(); |
| 2962 for (i = 0; i < iSize; ++i) { | 3201 for (int32_t i = 0; i < iSize; ++i) { |
| 2963 ((CPDF_Object *)m_arrayAcroforms.GetAt(i))->Release(); | 3202 ((CPDF_Object*)m_arrayAcroforms.GetAt(i))->Release(); |
| 2964 } | 3203 } |
| 2965 } | 3204 m_arrayAcroforms.RemoveAll(); |
| 2966 void CPDF_DataAvail::SetDocument(CPDF_Document* pDoc) | 3205 } else { |
| 2967 { | 3206 m_objs_array.RemoveAll(); |
| 2968 m_pDocument = pDoc; | 3207 m_objs_array.Append(new_objs_array); |
| 2969 } | 3208 } |
| 2970 FX_DWORD CPDF_DataAvail::GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset) | 3209 return bRet; |
| 2971 { | 3210 } |
| 2972 CPDF_Parser *pParser = (CPDF_Parser *)(m_pDocument->GetParser()); | 3211 FX_BOOL CPDF_DataAvail::CheckAcroForm(IFX_DownloadHints* pHints) { |
| 2973 if (pParser == NULL) { | 3212 FX_BOOL bExist = FALSE; |
| 2974 return 0; | 3213 m_pAcroForm = GetObject(m_dwAcroFormObjNum, pHints, &bExist); |
| 2975 } | 3214 if (!bExist) { |
| 2976 if (objnum >= (FX_DWORD)pParser->m_CrossRef.GetSize()) { | |
| 2977 return 0; | |
| 2978 } | |
| 2979 if (pParser->m_V5Type[objnum] == 2) { | |
| 2980 objnum = (FX_DWORD)pParser->m_CrossRef[objnum]; | |
| 2981 } | |
| 2982 if (pParser->m_V5Type[objnum] == 1 || pParser->m_V5Type[objnum] == 255) { | |
| 2983 offset = pParser->m_CrossRef[objnum]; | |
| 2984 if (offset == 0) { | |
| 2985 return 0; | |
| 2986 } | |
| 2987 void* pResult = FXSYS_bsearch(&offset, pParser->m_SortedOffset.GetData()
, pParser->m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); | |
| 2988 if (pResult == NULL) { | |
| 2989 return 0; | |
| 2990 } | |
| 2991 if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)pParser->m_SortedOffset.GetDat
a() == pParser->m_SortedOffset.GetSize() - 1) { | |
| 2992 return 0; | |
| 2993 } | |
| 2994 return (FX_DWORD)(((FX_FILESIZE*)pResult)[1] - offset); | |
| 2995 } | |
| 2996 return 0; | |
| 2997 } | |
| 2998 FX_BOOL CPDF_DataAvail::IsObjectsAvail(CFX_PtrArray& obj_array, FX_BOOL bParsePa
ge, IFX_DownloadHints* pHints, CFX_PtrArray &ret_array) | |
| 2999 { | |
| 3000 if (!obj_array.GetSize()) { | |
| 3001 return TRUE; | |
| 3002 } | |
| 3003 FX_DWORD count = 0; | |
| 3004 CFX_PtrArray new_obj_array; | |
| 3005 int32_t i = 0; | |
| 3006 for (i = 0; i < obj_array.GetSize(); i++) { | |
| 3007 CPDF_Object *pObj = (CPDF_Object *)obj_array[i]; | |
| 3008 if (!pObj) { | |
| 3009 continue; | |
| 3010 } | |
| 3011 int32_t type = pObj->GetType(); | |
| 3012 switch (type) { | |
| 3013 case PDFOBJ_ARRAY: { | |
| 3014 CPDF_Array *pArray = pObj->GetArray(); | |
| 3015 for (FX_DWORD k = 0; k < pArray->GetCount(); k++) { | |
| 3016 new_obj_array.Add(pArray->GetElement(k)); | |
| 3017 } | |
| 3018 } | |
| 3019 break; | |
| 3020 case PDFOBJ_STREAM: | |
| 3021 pObj = pObj->GetDict(); | |
| 3022 case PDFOBJ_DICTIONARY: { | |
| 3023 CPDF_Dictionary *pDict = pObj->GetDict(); | |
| 3024 if (pDict && pDict->GetString("Type") == "Page" && !bParsePa
ge) { | |
| 3025 continue; | |
| 3026 } | |
| 3027 FX_POSITION pos = pDict->GetStartPos(); | |
| 3028 while (pos) { | |
| 3029 CPDF_Object *value; | |
| 3030 CFX_ByteString key; | |
| 3031 value = pDict->GetNextElement(pos, key); | |
| 3032 if (key != "Parent") { | |
| 3033 new_obj_array.Add(value); | |
| 3034 } | |
| 3035 } | |
| 3036 } | |
| 3037 break; | |
| 3038 case PDFOBJ_REFERENCE: { | |
| 3039 CPDF_Reference *pRef = (CPDF_Reference*)pObj; | |
| 3040 FX_DWORD dwNum = pRef->GetRefObjNum(); | |
| 3041 FX_FILESIZE offset; | |
| 3042 FX_DWORD original_size = GetObjectSize(dwNum, offset); | |
| 3043 pdfium::base::CheckedNumeric<FX_DWORD> size = original_size; | |
| 3044 if (size.ValueOrDefault(0) == 0 || offset < 0 || offset >= m
_dwFileLen) { | |
| 3045 break; | |
| 3046 } | |
| 3047 | |
| 3048 size += offset; | |
| 3049 size += 512; | |
| 3050 if (!size.IsValid()) { | |
| 3051 break; | |
| 3052 } | |
| 3053 if (size.ValueOrDie() > m_dwFileLen) { | |
| 3054 size = m_dwFileLen - offset; | |
| 3055 } else { | |
| 3056 size = original_size + 512; | |
| 3057 } | |
| 3058 if (!size.IsValid()) { | |
| 3059 break; | |
| 3060 } | |
| 3061 if (!m_pFileAvail->IsDataAvail(offset, size.ValueOrDie())) { | |
| 3062 pHints->AddSegment(offset, size.ValueOrDie()); | |
| 3063 ret_array.Add(pObj); | |
| 3064 count++; | |
| 3065 } else if (!m_objnum_array.Find(dwNum)) { | |
| 3066 m_objnum_array.AddObjNum(dwNum); | |
| 3067 CPDF_Object *pReferred = m_pDocument->GetIndirectObject(
pRef->GetRefObjNum(), NULL); | |
| 3068 if (pReferred) { | |
| 3069 new_obj_array.Add(pReferred); | |
| 3070 } | |
| 3071 } | |
| 3072 } | |
| 3073 break; | |
| 3074 } | |
| 3075 } | |
| 3076 if (count > 0) { | |
| 3077 int32_t iSize = new_obj_array.GetSize(); | |
| 3078 for (i = 0; i < iSize; ++i) { | |
| 3079 CPDF_Object *pObj = (CPDF_Object *)new_obj_array[i]; | |
| 3080 int32_t type = pObj->GetType(); | |
| 3081 if (type == PDFOBJ_REFERENCE) { | |
| 3082 CPDF_Reference *pRef = (CPDF_Reference *)pObj; | |
| 3083 FX_DWORD dwNum = pRef->GetRefObjNum(); | |
| 3084 if (!m_objnum_array.Find(dwNum)) { | |
| 3085 ret_array.Add(pObj); | |
| 3086 } | |
| 3087 } else { | |
| 3088 ret_array.Add(pObj); | |
| 3089 } | |
| 3090 } | |
| 3091 return FALSE; | |
| 3092 } | |
| 3093 obj_array.RemoveAll(); | |
| 3094 obj_array.Append(new_obj_array); | |
| 3095 return IsObjectsAvail(obj_array, FALSE, pHints, ret_array); | |
| 3096 } | |
| 3097 FX_BOOL CPDF_DataAvail::IsDocAvail(IFX_DownloadHints* pHints) | |
| 3098 { | |
| 3099 if (!m_dwFileLen && m_pFileRead) { | |
| 3100 m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize(); | |
| 3101 if (!m_dwFileLen) { | |
| 3102 return TRUE; | |
| 3103 } | |
| 3104 } | |
| 3105 while (!m_bDocAvail) { | |
| 3106 if (!CheckDocStatus(pHints)) { | |
| 3107 return FALSE; | |
| 3108 } | |
| 3109 } | |
| 3110 return TRUE; | |
| 3111 } | |
| 3112 FX_BOOL CPDF_DataAvail::CheckAcroFormSubObject(IFX_DownloadHints* pHints) | |
| 3113 { | |
| 3114 if (!m_objs_array.GetSize()) { | |
| 3115 m_objs_array.RemoveAll(); | |
| 3116 m_objnum_array.RemoveAll(); | |
| 3117 CFX_PtrArray obj_array; | |
| 3118 obj_array.Append(m_arrayAcroforms); | |
| 3119 FX_BOOL bRet = IsObjectsAvail(obj_array, FALSE, pHints, m_objs_array); | |
| 3120 if (bRet) { | |
| 3121 m_objs_array.RemoveAll(); | |
| 3122 } | |
| 3123 return bRet; | |
| 3124 } | |
| 3125 CFX_PtrArray new_objs_array; | |
| 3126 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); | |
| 3127 if (bRet) { | |
| 3128 int32_t iSize = m_arrayAcroforms.GetSize(); | |
| 3129 for (int32_t i = 0; i < iSize; ++i) { | |
| 3130 ((CPDF_Object *)m_arrayAcroforms.GetAt(i))->Release(); | |
| 3131 } | |
| 3132 m_arrayAcroforms.RemoveAll(); | |
| 3133 } else { | |
| 3134 m_objs_array.RemoveAll(); | |
| 3135 m_objs_array.Append(new_objs_array); | |
| 3136 } | |
| 3137 return bRet; | |
| 3138 } | |
| 3139 FX_BOOL CPDF_DataAvail::CheckAcroForm(IFX_DownloadHints* pHints) | |
| 3140 { | |
| 3141 FX_BOOL bExist = FALSE; | |
| 3142 m_pAcroForm = GetObject(m_dwAcroFormObjNum, pHints, &bExist); | |
| 3143 if (!bExist) { | |
| 3144 m_docStatus = PDF_DATAAVAIL_PAGETREE; | |
| 3145 return TRUE; | |
| 3146 } | |
| 3147 if (!m_pAcroForm) { | |
| 3148 if (m_docStatus == PDF_DATAAVAIL_ERROR) { | |
| 3149 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; | |
| 3150 return TRUE; | |
| 3151 } | |
| 3152 return FALSE; | |
| 3153 } | |
| 3154 m_arrayAcroforms.Add(m_pAcroForm); | |
| 3155 m_docStatus = PDF_DATAAVAIL_PAGETREE; | 3215 m_docStatus = PDF_DATAAVAIL_PAGETREE; |
| 3156 return TRUE; | 3216 return TRUE; |
| 3157 } | 3217 } |
| 3158 FX_BOOL CPDF_DataAvail::CheckDocStatus(IFX_DownloadHints *pHints) | 3218 if (!m_pAcroForm) { |
| 3159 { | 3219 if (m_docStatus == PDF_DATAAVAIL_ERROR) { |
| 3160 switch (m_docStatus) { | 3220 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; |
| 3161 case PDF_DATAAVAIL_HEADER: | 3221 return TRUE; |
| 3162 return CheckHeader(pHints); | 3222 } |
| 3163 case PDF_DATAAVAIL_FIRSTPAGE: | 3223 return FALSE; |
| 3164 case PDF_DATAAVAIL_FIRSTPAGE_PREPARE: | 3224 } |
| 3165 return CheckFirstPage(pHints); | 3225 m_arrayAcroforms.Add(m_pAcroForm); |
| 3166 case PDF_DATAAVAIL_END: | 3226 m_docStatus = PDF_DATAAVAIL_PAGETREE; |
| 3167 return CheckEnd(pHints); | 3227 return TRUE; |
| 3168 case PDF_DATAAVAIL_CROSSREF: | 3228 } |
| 3169 return CheckCrossRef(pHints); | 3229 FX_BOOL CPDF_DataAvail::CheckDocStatus(IFX_DownloadHints* pHints) { |
| 3170 case PDF_DATAAVAIL_CROSSREF_ITEM: | 3230 switch (m_docStatus) { |
| 3171 return CheckCrossRefItem(pHints); | 3231 case PDF_DATAAVAIL_HEADER: |
| 3172 case PDF_DATAAVAIL_CROSSREF_STREAM: | 3232 return CheckHeader(pHints); |
| 3173 return CheckAllCrossRefStream(pHints); | 3233 case PDF_DATAAVAIL_FIRSTPAGE: |
| 3174 case PDF_DATAAVAIL_TRAILER: | 3234 case PDF_DATAAVAIL_FIRSTPAGE_PREPARE: |
| 3175 return CheckTrailer(pHints); | 3235 return CheckFirstPage(pHints); |
| 3176 case PDF_DATAAVAIL_TRAILER_APPEND: | 3236 case PDF_DATAAVAIL_END: |
| 3177 return CheckTrailerAppend(pHints); | 3237 return CheckEnd(pHints); |
| 3178 case PDF_DATAAVAIL_LOADALLCRSOSSREF: | 3238 case PDF_DATAAVAIL_CROSSREF: |
| 3179 return LoadAllXref(pHints); | 3239 return CheckCrossRef(pHints); |
| 3180 case PDF_DATAAVAIL_LOADALLFILE: | 3240 case PDF_DATAAVAIL_CROSSREF_ITEM: |
| 3181 return LoadAllFile(pHints); | 3241 return CheckCrossRefItem(pHints); |
| 3182 case PDF_DATAAVAIL_ROOT: | 3242 case PDF_DATAAVAIL_CROSSREF_STREAM: |
| 3183 return CheckRoot(pHints); | 3243 return CheckAllCrossRefStream(pHints); |
| 3184 case PDF_DATAAVAIL_INFO: | 3244 case PDF_DATAAVAIL_TRAILER: |
| 3185 return CheckInfo(pHints); | 3245 return CheckTrailer(pHints); |
| 3186 case PDF_DATAAVAIL_ACROFORM: | 3246 case PDF_DATAAVAIL_TRAILER_APPEND: |
| 3187 return CheckAcroForm(pHints); | 3247 return CheckTrailerAppend(pHints); |
| 3188 case PDF_DATAAVAIL_PAGETREE: | 3248 case PDF_DATAAVAIL_LOADALLCRSOSSREF: |
| 3189 if (m_bTotalLoadPageTree) { | 3249 return LoadAllXref(pHints); |
| 3190 return CheckPages(pHints); | 3250 case PDF_DATAAVAIL_LOADALLFILE: |
| 3191 } | 3251 return LoadAllFile(pHints); |
| 3192 return LoadDocPages(pHints); | 3252 case PDF_DATAAVAIL_ROOT: |
| 3193 case PDF_DATAAVAIL_PAGE: | 3253 return CheckRoot(pHints); |
| 3194 if (m_bTotalLoadPageTree) { | 3254 case PDF_DATAAVAIL_INFO: |
| 3195 return CheckPage(pHints); | 3255 return CheckInfo(pHints); |
| 3196 } | 3256 case PDF_DATAAVAIL_ACROFORM: |
| 3197 m_docStatus = PDF_DATAAVAIL_PAGE_LATERLOAD; | 3257 return CheckAcroForm(pHints); |
| 3198 return TRUE; | 3258 case PDF_DATAAVAIL_PAGETREE: |
| 3199 case PDF_DATAAVAIL_ERROR: | 3259 if (m_bTotalLoadPageTree) { |
| 3200 return LoadAllFile(pHints); | 3260 return CheckPages(pHints); |
| 3201 case PDF_DATAAVAIL_PAGE_LATERLOAD: | 3261 } |
| 3202 m_docStatus = PDF_DATAAVAIL_PAGE; | 3262 return LoadDocPages(pHints); |
| 3203 default: | 3263 case PDF_DATAAVAIL_PAGE: |
| 3204 m_bDocAvail = TRUE; | 3264 if (m_bTotalLoadPageTree) { |
| 3205 return TRUE; | 3265 return CheckPage(pHints); |
| 3206 } | 3266 } |
| 3207 } | 3267 m_docStatus = PDF_DATAAVAIL_PAGE_LATERLOAD; |
| 3208 FX_BOOL»CPDF_DataAvail::CheckPageStatus(IFX_DownloadHints* pHints) | 3268 return TRUE; |
| 3209 { | 3269 case PDF_DATAAVAIL_ERROR: |
| 3210 switch (m_docStatus) { | 3270 return LoadAllFile(pHints); |
| 3211 case PDF_DATAAVAIL_PAGETREE: | 3271 case PDF_DATAAVAIL_PAGE_LATERLOAD: |
| 3212 return CheckPages(pHints); | 3272 m_docStatus = PDF_DATAAVAIL_PAGE; |
| 3213 case PDF_DATAAVAIL_PAGE: | 3273 default: |
| 3214 return CheckPage(pHints); | 3274 m_bDocAvail = TRUE; |
| 3215 case PDF_DATAAVAIL_ERROR: | 3275 return TRUE; |
| 3216 return LoadAllFile(pHints); | 3276 } |
| 3217 default: | 3277 } |
| 3218 m_bPagesTreeLoad = TRUE; | 3278 FX_BOOL CPDF_DataAvail::CheckPageStatus(IFX_DownloadHints* pHints) { |
| 3219 m_bPagesLoad = TRUE; | 3279 switch (m_docStatus) { |
| 3220 return TRUE; | 3280 case PDF_DATAAVAIL_PAGETREE: |
| 3221 } | 3281 return CheckPages(pHints); |
| 3222 } | 3282 case PDF_DATAAVAIL_PAGE: |
| 3223 FX_BOOL CPDF_DataAvail::LoadAllFile(IFX_DownloadHints* pHints) | 3283 return CheckPage(pHints); |
| 3224 { | 3284 case PDF_DATAAVAIL_ERROR: |
| 3225 if (m_pFileAvail->IsDataAvail(0, (FX_DWORD)m_dwFileLen)) { | 3285 return LoadAllFile(pHints); |
| 3226 m_docStatus = PDF_DATAAVAIL_DONE; | 3286 default: |
| 3227 return TRUE; | 3287 m_bPagesTreeLoad = TRUE; |
| 3228 } | 3288 m_bPagesLoad = TRUE; |
| 3229 pHints->AddSegment(0, (FX_DWORD)m_dwFileLen); | 3289 return TRUE; |
| 3230 return FALSE; | 3290 } |
| 3231 } | 3291 } |
| 3232 FX_BOOL CPDF_DataAvail::LoadAllXref(IFX_DownloadHints* pHints) | 3292 FX_BOOL CPDF_DataAvail::LoadAllFile(IFX_DownloadHints* pHints) { |
| 3233 { | 3293 if (m_pFileAvail->IsDataAvail(0, (FX_DWORD)m_dwFileLen)) { |
| 3234 m_parser.m_Syntax.InitParser(m_pFileRead, (FX_DWORD)m_dwHeaderOffset); | 3294 m_docStatus = PDF_DATAAVAIL_DONE; |
| 3235 m_parser.m_bOwnFileRead = FALSE; | |
| 3236 if (!m_parser.LoadAllCrossRefV4(m_dwLastXRefOffset) && !m_parser.LoadAllCros
sRefV5(m_dwLastXRefOffset)) { | |
| 3237 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; | |
| 3238 return FALSE; | |
| 3239 } | |
| 3240 FXSYS_qsort(m_parser.m_SortedOffset.GetData(), m_parser.m_SortedOffset.GetSi
ze(), sizeof(FX_FILESIZE), _CompareFileSize); | |
| 3241 m_dwRootObjNum = m_parser.GetRootObjNum(); | |
| 3242 m_dwInfoObjNum = m_parser.GetInfoObjNum(); | |
| 3243 m_pCurrentParser = &m_parser; | |
| 3244 m_docStatus = PDF_DATAAVAIL_ROOT; | |
| 3245 return TRUE; | 3295 return TRUE; |
| 3246 } | 3296 } |
| 3247 CPDF_Object* CPDF_DataAvail::GetObject(FX_DWORD objnum, IFX_DownloadHints* pHint
s, FX_BOOL *pExistInFile) | 3297 pHints->AddSegment(0, (FX_DWORD)m_dwFileLen); |
| 3248 { | 3298 return FALSE; |
| 3249 CPDF_Object *pRet = NULL; | 3299 } |
| 3250 FX_DWORD original_size = 0; | 3300 FX_BOOL CPDF_DataAvail::LoadAllXref(IFX_DownloadHints* pHints) { |
| 3251 FX_FILESIZE offset = 0; | 3301 m_parser.m_Syntax.InitParser(m_pFileRead, (FX_DWORD)m_dwHeaderOffset); |
| 3252 CPDF_Parser *pParser = NULL; | 3302 m_parser.m_bOwnFileRead = FALSE; |
| 3253 | 3303 if (!m_parser.LoadAllCrossRefV4(m_dwLastXRefOffset) && |
| 3254 if (pExistInFile) { | 3304 !m_parser.LoadAllCrossRefV5(m_dwLastXRefOffset)) { |
| 3255 *pExistInFile = TRUE; | 3305 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; |
| 3256 } | 3306 return FALSE; |
| 3257 | 3307 } |
| 3258 if (m_pDocument == NULL) { | 3308 FXSYS_qsort(m_parser.m_SortedOffset.GetData(), |
| 3259 original_size = (FX_DWORD)m_parser.GetObjectSize(objnum); | 3309 m_parser.m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), |
| 3260 offset = m_parser.GetObjectOffset(objnum); | 3310 _CompareFileSize); |
| 3261 pParser = &m_parser; | 3311 m_dwRootObjNum = m_parser.GetRootObjNum(); |
| 3312 m_dwInfoObjNum = m_parser.GetInfoObjNum(); |
| 3313 m_pCurrentParser = &m_parser; |
| 3314 m_docStatus = PDF_DATAAVAIL_ROOT; |
| 3315 return TRUE; |
| 3316 } |
| 3317 CPDF_Object* CPDF_DataAvail::GetObject(FX_DWORD objnum, |
| 3318 IFX_DownloadHints* pHints, |
| 3319 FX_BOOL* pExistInFile) { |
| 3320 CPDF_Object* pRet = NULL; |
| 3321 FX_DWORD original_size = 0; |
| 3322 FX_FILESIZE offset = 0; |
| 3323 CPDF_Parser* pParser = NULL; |
| 3324 |
| 3325 if (pExistInFile) { |
| 3326 *pExistInFile = TRUE; |
| 3327 } |
| 3328 |
| 3329 if (m_pDocument == NULL) { |
| 3330 original_size = (FX_DWORD)m_parser.GetObjectSize(objnum); |
| 3331 offset = m_parser.GetObjectOffset(objnum); |
| 3332 pParser = &m_parser; |
| 3333 } else { |
| 3334 original_size = GetObjectSize(objnum, offset); |
| 3335 pParser = (CPDF_Parser*)(m_pDocument->GetParser()); |
| 3336 } |
| 3337 |
| 3338 pdfium::base::CheckedNumeric<FX_DWORD> size = original_size; |
| 3339 if (size.ValueOrDefault(0) == 0 || offset < 0 || offset >= m_dwFileLen) { |
| 3340 if (pExistInFile) |
| 3341 *pExistInFile = FALSE; |
| 3342 |
| 3343 return NULL; |
| 3344 } |
| 3345 |
| 3346 size += offset; |
| 3347 size += 512; |
| 3348 if (!size.IsValid()) { |
| 3349 return NULL; |
| 3350 } |
| 3351 |
| 3352 if (size.ValueOrDie() > m_dwFileLen) { |
| 3353 size = m_dwFileLen - offset; |
| 3354 } else { |
| 3355 size = original_size + 512; |
| 3356 } |
| 3357 |
| 3358 if (!size.IsValid()) { |
| 3359 return NULL; |
| 3360 } |
| 3361 |
| 3362 if (!m_pFileAvail->IsDataAvail(offset, size.ValueOrDie())) { |
| 3363 pHints->AddSegment(offset, size.ValueOrDie()); |
| 3364 return NULL; |
| 3365 } |
| 3366 |
| 3367 if (pParser) { |
| 3368 pRet = pParser->ParseIndirectObject(NULL, objnum, NULL); |
| 3369 } |
| 3370 |
| 3371 if (!pRet && pExistInFile) { |
| 3372 *pExistInFile = FALSE; |
| 3373 } |
| 3374 |
| 3375 return pRet; |
| 3376 } |
| 3377 |
| 3378 FX_BOOL CPDF_DataAvail::CheckInfo(IFX_DownloadHints* pHints) { |
| 3379 FX_BOOL bExist = FALSE; |
| 3380 CPDF_Object* pInfo = GetObject(m_dwInfoObjNum, pHints, &bExist); |
| 3381 if (!bExist) { |
| 3382 if (m_bHaveAcroForm) { |
| 3383 m_docStatus = PDF_DATAAVAIL_ACROFORM; |
| 3262 } else { | 3384 } else { |
| 3263 original_size = GetObjectSize(objnum, offset); | 3385 m_docStatus = PDF_DATAAVAIL_PAGETREE; |
| 3264 pParser = (CPDF_Parser *)(m_pDocument->GetParser()); | 3386 } |
| 3265 } | 3387 return TRUE; |
| 3266 | 3388 } |
| 3267 pdfium::base::CheckedNumeric<FX_DWORD> size = original_size; | 3389 if (!pInfo) { |
| 3268 if (size.ValueOrDefault(0) == 0 || offset < 0 || offset >= m_dwFileLen) { | 3390 if (m_docStatus == PDF_DATAAVAIL_ERROR) { |
| 3269 if (pExistInFile) | 3391 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; |
| 3270 *pExistInFile = FALSE; | 3392 return TRUE; |
| 3271 | 3393 } |
| 3272 return NULL; | 3394 if (m_Pos == m_dwFileLen) { |
| 3273 } | 3395 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 3274 | 3396 } |
| 3275 size += offset; | 3397 return FALSE; |
| 3276 size += 512; | 3398 } |
| 3277 if (!size.IsValid()) { | 3399 if (pInfo) { |
| 3278 return NULL; | 3400 pInfo->Release(); |
| 3279 } | 3401 } |
| 3280 | 3402 if (m_bHaveAcroForm) { |
| 3281 if (size.ValueOrDie() > m_dwFileLen) { | 3403 m_docStatus = PDF_DATAAVAIL_ACROFORM; |
| 3282 size = m_dwFileLen - offset; | 3404 } else { |
| 3405 m_docStatus = PDF_DATAAVAIL_PAGETREE; |
| 3406 } |
| 3407 return TRUE; |
| 3408 } |
| 3409 FX_BOOL CPDF_DataAvail::CheckRoot(IFX_DownloadHints* pHints) { |
| 3410 FX_BOOL bExist = FALSE; |
| 3411 m_pRoot = GetObject(m_dwRootObjNum, pHints, &bExist); |
| 3412 if (!bExist) { |
| 3413 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; |
| 3414 return TRUE; |
| 3415 } |
| 3416 if (!m_pRoot) { |
| 3417 if (m_docStatus == PDF_DATAAVAIL_ERROR) { |
| 3418 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; |
| 3419 return TRUE; |
| 3420 } |
| 3421 return FALSE; |
| 3422 } |
| 3423 CPDF_Dictionary* pDict = m_pRoot->GetDict(); |
| 3424 if (!pDict) { |
| 3425 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 3426 return FALSE; |
| 3427 } |
| 3428 CPDF_Reference* pRef = (CPDF_Reference*)pDict->GetElement(FX_BSTRC("Pages")); |
| 3429 if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) { |
| 3430 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 3431 return FALSE; |
| 3432 } |
| 3433 m_PagesObjNum = pRef->GetRefObjNum(); |
| 3434 CPDF_Reference* pAcroFormRef = |
| 3435 (CPDF_Reference*)m_pRoot->GetDict()->GetElement(FX_BSTRC("AcroForm")); |
| 3436 if (pAcroFormRef && pAcroFormRef->GetType() == PDFOBJ_REFERENCE) { |
| 3437 m_bHaveAcroForm = TRUE; |
| 3438 m_dwAcroFormObjNum = pAcroFormRef->GetRefObjNum(); |
| 3439 } |
| 3440 if (m_dwInfoObjNum) { |
| 3441 m_docStatus = PDF_DATAAVAIL_INFO; |
| 3442 } else { |
| 3443 if (m_bHaveAcroForm) { |
| 3444 m_docStatus = PDF_DATAAVAIL_ACROFORM; |
| 3283 } else { | 3445 } else { |
| 3284 size = original_size + 512; | 3446 m_docStatus = PDF_DATAAVAIL_PAGETREE; |
| 3285 } | 3447 } |
| 3286 | 3448 } |
| 3287 if (!size.IsValid()) { | 3449 return TRUE; |
| 3288 return NULL; | 3450 } |
| 3289 } | 3451 FX_BOOL CPDF_DataAvail::PreparePageItem() { |
| 3290 | 3452 CPDF_Dictionary* pRoot = m_pDocument->GetRoot(); |
| 3291 if (!m_pFileAvail->IsDataAvail(offset, size.ValueOrDie())) { | 3453 CPDF_Reference* pRef = |
| 3292 pHints->AddSegment(offset, size.ValueOrDie()); | 3454 pRoot ? (CPDF_Reference*)pRoot->GetElement(FX_BSTRC("Pages")) : NULL; |
| 3293 return NULL; | 3455 if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) { |
| 3294 } | 3456 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 3295 | 3457 return FALSE; |
| 3296 if (pParser) { | 3458 } |
| 3297 pRet = pParser->ParseIndirectObject(NULL, objnum, NULL); | 3459 m_PagesObjNum = pRef->GetRefObjNum(); |
| 3298 } | 3460 m_pCurrentParser = (CPDF_Parser*)m_pDocument->GetParser(); |
| 3299 | 3461 m_docStatus = PDF_DATAAVAIL_PAGETREE; |
| 3300 if (!pRet && pExistInFile) { | 3462 return TRUE; |
| 3301 *pExistInFile = FALSE; | 3463 } |
| 3302 } | 3464 FX_BOOL CPDF_DataAvail::IsFirstCheck(int iPage) { |
| 3303 | 3465 if (NULL == m_pageMapCheckState) { |
| 3304 return pRet; | 3466 m_pageMapCheckState = new CFX_CMapDWordToDWord(); |
| 3305 } | 3467 } |
| 3306 | 3468 FX_DWORD dwValue = 0; |
| 3307 FX_BOOL CPDF_DataAvail::CheckInfo(IFX_DownloadHints* pHints) | 3469 if (!m_pageMapCheckState->Lookup(iPage, dwValue)) { |
| 3308 { | |
| 3309 FX_BOOL bExist = FALSE; | |
| 3310 CPDF_Object *pInfo = GetObject(m_dwInfoObjNum, pHints, &bExist); | |
| 3311 if (!bExist) { | |
| 3312 if (m_bHaveAcroForm) { | |
| 3313 m_docStatus = PDF_DATAAVAIL_ACROFORM; | |
| 3314 } else { | |
| 3315 m_docStatus = PDF_DATAAVAIL_PAGETREE; | |
| 3316 } | |
| 3317 return TRUE; | |
| 3318 } | |
| 3319 if (!pInfo) { | |
| 3320 if (m_docStatus == PDF_DATAAVAIL_ERROR) { | |
| 3321 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; | |
| 3322 return TRUE; | |
| 3323 } | |
| 3324 if (m_Pos == m_dwFileLen) { | |
| 3325 m_docStatus = PDF_DATAAVAIL_ERROR; | |
| 3326 } | |
| 3327 return FALSE; | |
| 3328 } | |
| 3329 if (pInfo) { | |
| 3330 pInfo->Release(); | |
| 3331 } | |
| 3332 if (m_bHaveAcroForm) { | |
| 3333 m_docStatus = PDF_DATAAVAIL_ACROFORM; | |
| 3334 } else { | |
| 3335 m_docStatus = PDF_DATAAVAIL_PAGETREE; | |
| 3336 } | |
| 3337 return TRUE; | |
| 3338 } | |
| 3339 FX_BOOL CPDF_DataAvail::CheckRoot(IFX_DownloadHints* pHints) | |
| 3340 { | |
| 3341 FX_BOOL bExist = FALSE; | |
| 3342 m_pRoot = GetObject(m_dwRootObjNum, pHints, &bExist); | |
| 3343 if (!bExist) { | |
| 3344 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; | |
| 3345 return TRUE; | |
| 3346 } | |
| 3347 if (!m_pRoot) { | |
| 3348 if (m_docStatus == PDF_DATAAVAIL_ERROR) { | |
| 3349 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; | |
| 3350 return TRUE; | |
| 3351 } | |
| 3352 return FALSE; | |
| 3353 } | |
| 3354 CPDF_Dictionary* pDict = m_pRoot->GetDict(); | |
| 3355 if (!pDict) { | |
| 3356 m_docStatus = PDF_DATAAVAIL_ERROR; | |
| 3357 return FALSE; | |
| 3358 } | |
| 3359 CPDF_Reference* pRef = (CPDF_Reference*)pDict->GetElement(FX_BSTRC("Pages"))
; | |
| 3360 if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) { | |
| 3361 m_docStatus = PDF_DATAAVAIL_ERROR; | |
| 3362 return FALSE; | |
| 3363 } | |
| 3364 m_PagesObjNum = pRef->GetRefObjNum(); | |
| 3365 CPDF_Reference* pAcroFormRef = (CPDF_Reference*)m_pRoot->GetDict()->GetEleme
nt(FX_BSTRC("AcroForm")); | |
| 3366 if (pAcroFormRef && pAcroFormRef->GetType() == PDFOBJ_REFERENCE) { | |
| 3367 m_bHaveAcroForm = TRUE; | |
| 3368 m_dwAcroFormObjNum = pAcroFormRef->GetRefObjNum(); | |
| 3369 } | |
| 3370 if (m_dwInfoObjNum) { | |
| 3371 m_docStatus = PDF_DATAAVAIL_INFO; | |
| 3372 } else { | |
| 3373 if (m_bHaveAcroForm) { | |
| 3374 m_docStatus = PDF_DATAAVAIL_ACROFORM; | |
| 3375 } else { | |
| 3376 m_docStatus = PDF_DATAAVAIL_PAGETREE; | |
| 3377 } | |
| 3378 } | |
| 3379 return TRUE; | |
| 3380 } | |
| 3381 FX_BOOL CPDF_DataAvail::PreparePageItem() | |
| 3382 { | |
| 3383 CPDF_Dictionary *pRoot = m_pDocument->GetRoot(); | |
| 3384 CPDF_Reference* pRef = pRoot ? (CPDF_Reference*)pRoot->GetElement(FX_BSTRC("
Pages")) : NULL; | |
| 3385 if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) { | |
| 3386 m_docStatus = PDF_DATAAVAIL_ERROR; | |
| 3387 return FALSE; | |
| 3388 } | |
| 3389 m_PagesObjNum = pRef->GetRefObjNum(); | |
| 3390 m_pCurrentParser = (CPDF_Parser *)m_pDocument->GetParser(); | |
| 3391 m_docStatus = PDF_DATAAVAIL_PAGETREE; | |
| 3392 return TRUE; | |
| 3393 } | |
| 3394 FX_BOOL CPDF_DataAvail::IsFirstCheck(int iPage) | |
| 3395 { | |
| 3396 if (NULL == m_pageMapCheckState) { | |
| 3397 m_pageMapCheckState = new CFX_CMapDWordToDWord(); | |
| 3398 } | |
| 3399 FX_DWORD dwValue = 0; | |
| 3400 if (!m_pageMapCheckState->Lookup(iPage, dwValue)) { | |
| 3401 m_pageMapCheckState->SetAt(iPage, 1); | |
| 3402 return TRUE; | |
| 3403 } | |
| 3404 if (dwValue != 0) { | |
| 3405 return FALSE; | |
| 3406 } | |
| 3407 m_pageMapCheckState->SetAt(iPage, 1); | 3470 m_pageMapCheckState->SetAt(iPage, 1); |
| 3408 return TRUE; | 3471 return TRUE; |
| 3409 } | 3472 } |
| 3410 void CPDF_DataAvail::ResetFirstCheck(int iPage) | 3473 if (dwValue != 0) { |
| 3411 { | 3474 return FALSE; |
| 3412 if (NULL == m_pageMapCheckState) { | 3475 } |
| 3413 m_pageMapCheckState = new CFX_CMapDWordToDWord(); | 3476 m_pageMapCheckState->SetAt(iPage, 1); |
| 3414 } | 3477 return TRUE; |
| 3415 FX_DWORD dwValue = 1; | 3478 } |
| 3416 if (!m_pageMapCheckState->Lookup(iPage, dwValue)) { | 3479 void CPDF_DataAvail::ResetFirstCheck(int iPage) { |
| 3417 return; | 3480 if (NULL == m_pageMapCheckState) { |
| 3418 } | 3481 m_pageMapCheckState = new CFX_CMapDWordToDWord(); |
| 3419 m_pageMapCheckState->SetAt(iPage, 0); | 3482 } |
| 3420 } | 3483 FX_DWORD dwValue = 1; |
| 3421 FX_BOOL CPDF_DataAvail::CheckPage(IFX_DownloadHints* pHints) | 3484 if (!m_pageMapCheckState->Lookup(iPage, dwValue)) { |
| 3422 { | 3485 return; |
| 3423 FX_DWORD iPageObjs = m_PageObjList.GetSize(); | 3486 } |
| 3424 CFX_DWordArray UnavailObjList; | 3487 m_pageMapCheckState->SetAt(iPage, 0); |
| 3425 for (FX_DWORD i = 0; i < iPageObjs; ++i) { | 3488 } |
| 3426 FX_DWORD dwPageObjNum = m_PageObjList.GetAt(i); | 3489 FX_BOOL CPDF_DataAvail::CheckPage(IFX_DownloadHints* pHints) { |
| 3427 FX_BOOL bExist = FALSE; | 3490 FX_DWORD iPageObjs = m_PageObjList.GetSize(); |
| 3428 CPDF_Object *pObj = GetObject(dwPageObjNum, pHints, &bExist); | 3491 CFX_DWordArray UnavailObjList; |
| 3429 if (!pObj) { | 3492 for (FX_DWORD i = 0; i < iPageObjs; ++i) { |
| 3430 if (bExist) { | 3493 FX_DWORD dwPageObjNum = m_PageObjList.GetAt(i); |
| 3431 UnavailObjList.Add(dwPageObjNum); | 3494 FX_BOOL bExist = FALSE; |
| 3432 } | 3495 CPDF_Object* pObj = GetObject(dwPageObjNum, pHints, &bExist); |
| 3433 continue; | 3496 if (!pObj) { |
| 3434 } | 3497 if (bExist) { |
| 3435 if (pObj->GetType() == PDFOBJ_ARRAY) { | 3498 UnavailObjList.Add(dwPageObjNum); |
| 3436 CPDF_Array *pArray = pObj->GetArray(); | 3499 } |
| 3437 if (pArray) { | 3500 continue; |
| 3438 int32_t iSize = pArray->GetCount(); | 3501 } |
| 3439 CPDF_Object *pItem = NULL; | 3502 if (pObj->GetType() == PDFOBJ_ARRAY) { |
| 3440 for (int32_t j = 0; j < iSize; ++j) { | 3503 CPDF_Array* pArray = pObj->GetArray(); |
| 3441 pItem = pArray->GetElement(j); | 3504 if (pArray) { |
| 3442 if (pItem && pItem->GetType() == PDFOBJ_REFERENCE) { | 3505 int32_t iSize = pArray->GetCount(); |
| 3443 UnavailObjList.Add(((CPDF_Reference *)pItem)->GetRefObjN
um()); | 3506 CPDF_Object* pItem = NULL; |
| 3444 } | 3507 for (int32_t j = 0; j < iSize; ++j) { |
| 3445 } | 3508 pItem = pArray->GetElement(j); |
| 3446 } | 3509 if (pItem && pItem->GetType() == PDFOBJ_REFERENCE) { |
| 3447 } | 3510 UnavailObjList.Add(((CPDF_Reference*)pItem)->GetRefObjNum()); |
| 3448 if (pObj->GetType() != PDFOBJ_DICTIONARY) { | 3511 } |
| 3449 pObj->Release(); | 3512 } |
| 3450 continue; | 3513 } |
| 3451 } | 3514 } |
| 3452 CFX_ByteString type = pObj->GetDict()->GetString(FX_BSTRC("Type")); | 3515 if (pObj->GetType() != PDFOBJ_DICTIONARY) { |
| 3453 if (type == FX_BSTRC("Pages")) { | 3516 pObj->Release(); |
| 3454 m_PagesArray.Add(pObj); | 3517 continue; |
| 3455 continue; | 3518 } |
| 3456 } | 3519 CFX_ByteString type = pObj->GetDict()->GetString(FX_BSTRC("Type")); |
| 3457 pObj->Release(); | 3520 if (type == FX_BSTRC("Pages")) { |
| 3458 } | 3521 m_PagesArray.Add(pObj); |
| 3459 m_PageObjList.RemoveAll(); | 3522 continue; |
| 3460 if (UnavailObjList.GetSize()) { | 3523 } |
| 3461 m_PageObjList.Append(UnavailObjList); | 3524 pObj->Release(); |
| 3462 return FALSE; | 3525 } |
| 3463 } | 3526 m_PageObjList.RemoveAll(); |
| 3464 FX_DWORD iPages = m_PagesArray.GetSize(); | 3527 if (UnavailObjList.GetSize()) { |
| 3465 for (FX_DWORD i = 0; i < iPages; i++) { | 3528 m_PageObjList.Append(UnavailObjList); |
| 3466 CPDF_Object *pPages = (CPDF_Object *)m_PagesArray.GetAt(i); | 3529 return FALSE; |
| 3467 if (!pPages) { | 3530 } |
| 3468 continue; | 3531 FX_DWORD iPages = m_PagesArray.GetSize(); |
| 3469 } | 3532 for (FX_DWORD i = 0; i < iPages; i++) { |
| 3470 if (!GetPageKids(m_pCurrentParser, pPages)) { | 3533 CPDF_Object* pPages = (CPDF_Object*)m_PagesArray.GetAt(i); |
| 3471 pPages->Release(); | 3534 if (!pPages) { |
| 3472 while (++i < iPages) { | 3535 continue; |
| 3473 pPages = (CPDF_Object *)m_PagesArray.GetAt(i); | 3536 } |
| 3474 pPages->Release(); | 3537 if (!GetPageKids(m_pCurrentParser, pPages)) { |
| 3475 } | 3538 pPages->Release(); |
| 3476 m_PagesArray.RemoveAll(); | 3539 while (++i < iPages) { |
| 3477 m_docStatus = PDF_DATAAVAIL_ERROR; | 3540 pPages = (CPDF_Object*)m_PagesArray.GetAt(i); |
| 3478 return FALSE; | |
| 3479 } | |
| 3480 pPages->Release(); | 3541 pPages->Release(); |
| 3481 } | 3542 } |
| 3482 m_PagesArray.RemoveAll(); | 3543 m_PagesArray.RemoveAll(); |
| 3483 if (!m_PageObjList.GetSize()) { | 3544 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 3484 m_docStatus = PDF_DATAAVAIL_DONE; | 3545 return FALSE; |
| 3485 } | 3546 } |
| 3547 pPages->Release(); |
| 3548 } |
| 3549 m_PagesArray.RemoveAll(); |
| 3550 if (!m_PageObjList.GetSize()) { |
| 3551 m_docStatus = PDF_DATAAVAIL_DONE; |
| 3552 } |
| 3553 return TRUE; |
| 3554 } |
| 3555 FX_BOOL CPDF_DataAvail::GetPageKids(CPDF_Parser* pParser, CPDF_Object* pPages) { |
| 3556 if (!pParser) { |
| 3557 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 3558 return FALSE; |
| 3559 } |
| 3560 CPDF_Dictionary* pDict = pPages->GetDict(); |
| 3561 CPDF_Object* pKids = pDict ? pDict->GetElement(FX_BSTRC("Kids")) : NULL; |
| 3562 if (!pKids) { |
| 3486 return TRUE; | 3563 return TRUE; |
| 3487 } | 3564 } |
| 3488 FX_BOOL CPDF_DataAvail::GetPageKids(CPDF_Parser *pParser, CPDF_Object *pPages) | 3565 switch (pKids->GetType()) { |
| 3489 { | 3566 case PDFOBJ_REFERENCE: { |
| 3490 if (!pParser) { | 3567 CPDF_Reference* pKid = (CPDF_Reference*)pKids; |
| 3491 m_docStatus = PDF_DATAAVAIL_ERROR; | 3568 m_PageObjList.Add(pKid->GetRefObjNum()); |
| 3492 return FALSE; | 3569 } break; |
| 3493 } | 3570 case PDFOBJ_ARRAY: { |
| 3494 CPDF_Dictionary* pDict = pPages->GetDict(); | 3571 CPDF_Array* pKidsArray = (CPDF_Array*)pKids; |
| 3495 CPDF_Object *pKids = pDict ? pDict->GetElement(FX_BSTRC("Kids")) : NULL; | 3572 for (FX_DWORD i = 0; i < pKidsArray->GetCount(); ++i) { |
| 3496 if (!pKids) { | 3573 CPDF_Object* pKid = (CPDF_Object*)pKidsArray->GetElement(i); |
| 3497 return TRUE; | 3574 if (pKid && pKid->GetType() == PDFOBJ_REFERENCE) { |
| 3498 } | 3575 m_PageObjList.Add(((CPDF_Reference*)pKid)->GetRefObjNum()); |
| 3499 switch (pKids->GetType()) { | 3576 } |
| 3500 case PDFOBJ_REFERENCE: { | 3577 } |
| 3501 CPDF_Reference *pKid = (CPDF_Reference *)pKids; | 3578 } break; |
| 3502 m_PageObjList.Add(pKid->GetRefObjNum()); | 3579 default: |
| 3503 } | 3580 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 3504 break; | 3581 return FALSE; |
| 3505 case PDFOBJ_ARRAY: { | 3582 } |
| 3506 CPDF_Array *pKidsArray = (CPDF_Array *)pKids; | 3583 return TRUE; |
| 3507 for (FX_DWORD i = 0; i < pKidsArray->GetCount(); ++i) { | 3584 } |
| 3508 CPDF_Object *pKid = (CPDF_Object *)pKidsArray->GetElement(i)
; | 3585 FX_BOOL CPDF_DataAvail::CheckPages(IFX_DownloadHints* pHints) { |
| 3509 if (pKid && pKid->GetType() == PDFOBJ_REFERENCE) { | 3586 FX_BOOL bExist = FALSE; |
| 3510 m_PageObjList.Add(((CPDF_Reference *)pKid)->GetRefObjNum
()); | 3587 CPDF_Object* pPages = GetObject(m_PagesObjNum, pHints, &bExist); |
| 3511 } | 3588 if (!bExist) { |
| 3512 } | 3589 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; |
| 3513 } | |
| 3514 break; | |
| 3515 default: | |
| 3516 m_docStatus = PDF_DATAAVAIL_ERROR; | |
| 3517 return FALSE; | |
| 3518 } | |
| 3519 return TRUE; | 3590 return TRUE; |
| 3520 } | 3591 } |
| 3521 FX_BOOL CPDF_DataAvail::CheckPages(IFX_DownloadHints* pHints) | 3592 if (!pPages) { |
| 3522 { | 3593 if (m_docStatus == PDF_DATAAVAIL_ERROR) { |
| 3523 FX_BOOL bExist = FALSE; | 3594 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; |
| 3524 CPDF_Object *pPages = GetObject(m_PagesObjNum, pHints, &bExist); | 3595 return TRUE; |
| 3525 if (!bExist) { | 3596 } |
| 3526 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; | 3597 return FALSE; |
| 3527 return TRUE; | 3598 } |
| 3528 } | 3599 if (!GetPageKids(m_pCurrentParser, pPages)) { |
| 3529 if (!pPages) { | |
| 3530 if (m_docStatus == PDF_DATAAVAIL_ERROR) { | |
| 3531 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; | |
| 3532 return TRUE; | |
| 3533 } | |
| 3534 return FALSE; | |
| 3535 } | |
| 3536 if (!GetPageKids(m_pCurrentParser, pPages)) { | |
| 3537 pPages->Release(); | |
| 3538 m_docStatus = PDF_DATAAVAIL_ERROR; | |
| 3539 return FALSE; | |
| 3540 } | |
| 3541 pPages->Release(); | 3600 pPages->Release(); |
| 3542 m_docStatus = PDF_DATAAVAIL_PAGE; | 3601 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 3543 return TRUE; | 3602 return FALSE; |
| 3544 } | 3603 } |
| 3545 FX_BOOL CPDF_DataAvail::CheckHeader(IFX_DownloadHints* pHints) | 3604 pPages->Release(); |
| 3546 { | 3605 m_docStatus = PDF_DATAAVAIL_PAGE; |
| 3547 FX_DWORD req_size = 1024; | 3606 return TRUE; |
| 3548 if ((FX_FILESIZE)req_size > m_dwFileLen) { | 3607 } |
| 3549 req_size = (FX_DWORD)m_dwFileLen; | 3608 FX_BOOL CPDF_DataAvail::CheckHeader(IFX_DownloadHints* pHints) { |
| 3550 } | 3609 FX_DWORD req_size = 1024; |
| 3551 if (m_pFileAvail->IsDataAvail(0, req_size)) { | 3610 if ((FX_FILESIZE)req_size > m_dwFileLen) { |
| 3552 uint8_t buffer[1024]; | 3611 req_size = (FX_DWORD)m_dwFileLen; |
| 3553 m_pFileRead->ReadBlock(buffer, 0, req_size); | 3612 } |
| 3554 if (IsLinearizedFile(buffer, req_size)) { | 3613 if (m_pFileAvail->IsDataAvail(0, req_size)) { |
| 3555 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE; | |
| 3556 } else { | |
| 3557 if (m_docStatus == PDF_DATAAVAIL_ERROR) { | |
| 3558 return FALSE; | |
| 3559 } | |
| 3560 m_docStatus = PDF_DATAAVAIL_END; | |
| 3561 } | |
| 3562 return TRUE; | |
| 3563 } | |
| 3564 pHints->AddSegment(0, req_size); | |
| 3565 return FALSE; | |
| 3566 } | |
| 3567 FX_BOOL CPDF_DataAvail::CheckFirstPage(IFX_DownloadHints *pHints) | |
| 3568 { | |
| 3569 CPDF_Dictionary* pDict = m_pLinearized->GetDict(); | |
| 3570 CPDF_Object *pEndOffSet = pDict ? pDict->GetElement(FX_BSTRC("E")) : NULL; | |
| 3571 if (!pEndOffSet) { | |
| 3572 m_docStatus = PDF_DATAAVAIL_ERROR; | |
| 3573 return FALSE; | |
| 3574 } | |
| 3575 CPDF_Object *pXRefOffset = pDict ? pDict->GetElement(FX_BSTRC("T")) : NULL; | |
| 3576 if (!pXRefOffset) { | |
| 3577 m_docStatus = PDF_DATAAVAIL_ERROR; | |
| 3578 return FALSE; | |
| 3579 } | |
| 3580 CPDF_Object *pFileLen = pDict ? pDict->GetElement(FX_BSTRC("L")) : NULL; | |
| 3581 if (!pFileLen) { | |
| 3582 m_docStatus = PDF_DATAAVAIL_ERROR; | |
| 3583 return FALSE; | |
| 3584 } | |
| 3585 FX_BOOL bNeedDownLoad = FALSE; | |
| 3586 if (pEndOffSet->GetType() == PDFOBJ_NUMBER) { | |
| 3587 FX_DWORD dwEnd = pEndOffSet->GetInteger(); | |
| 3588 dwEnd += 512; | |
| 3589 if ((FX_FILESIZE)dwEnd > m_dwFileLen) { | |
| 3590 dwEnd = (FX_DWORD)m_dwFileLen; | |
| 3591 } | |
| 3592 int32_t iStartPos = (int32_t)(m_dwFileLen > 1024 ? 1024 : m_dwFileLen); | |
| 3593 int32_t iSize = dwEnd > 1024 ? dwEnd - 1024 : 0; | |
| 3594 if (!m_pFileAvail->IsDataAvail(iStartPos, iSize)) { | |
| 3595 pHints->AddSegment(iStartPos, iSize); | |
| 3596 bNeedDownLoad = TRUE; | |
| 3597 } | |
| 3598 } | |
| 3599 m_dwLastXRefOffset = 0; | |
| 3600 FX_FILESIZE dwFileLen = 0; | |
| 3601 if (pXRefOffset->GetType() == PDFOBJ_NUMBER) { | |
| 3602 m_dwLastXRefOffset = pXRefOffset->GetInteger(); | |
| 3603 } | |
| 3604 if (pFileLen->GetType() == PDFOBJ_NUMBER) { | |
| 3605 dwFileLen = pFileLen->GetInteger(); | |
| 3606 } | |
| 3607 if (!m_pFileAvail->IsDataAvail(m_dwLastXRefOffset, (FX_DWORD)(dwFileLen - m_
dwLastXRefOffset))) { | |
| 3608 if (m_docStatus == PDF_DATAAVAIL_FIRSTPAGE)» { | |
| 3609 FX_DWORD dwSize = (FX_DWORD)(dwFileLen - m_dwLastXRefOffset); | |
| 3610 FX_FILESIZE offset = m_dwLastXRefOffset; | |
| 3611 if (dwSize < 512 && dwFileLen > 512) { | |
| 3612 dwSize = 512; | |
| 3613 offset = dwFileLen - 512; | |
| 3614 } | |
| 3615 pHints->AddSegment(offset, dwSize); | |
| 3616 } | |
| 3617 } else { | |
| 3618 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE; | |
| 3619 } | |
| 3620 if (!bNeedDownLoad && m_docStatus == PDF_DATAAVAIL_FIRSTPAGE_PREPARE) { | |
| 3621 m_docStatus = PDF_DATAAVAIL_DONE; | |
| 3622 return TRUE; | |
| 3623 } | |
| 3624 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE; | |
| 3625 return FALSE; | |
| 3626 } | |
| 3627 CPDF_Object» * CPDF_DataAvail::ParseIndirectObjectAt(FX_FILESIZE pos, FX_DWOR
D objnum) | |
| 3628 { | |
| 3629 FX_FILESIZE SavedPos = m_syntaxParser.SavePos(); | |
| 3630 m_syntaxParser.RestorePos(pos); | |
| 3631 FX_BOOL bIsNumber; | |
| 3632 CFX_ByteString word = m_syntaxParser.GetNextWord(bIsNumber); | |
| 3633 if (!bIsNumber) { | |
| 3634 return NULL; | |
| 3635 } | |
| 3636 FX_DWORD parser_objnum = FXSYS_atoi(word); | |
| 3637 if (objnum && parser_objnum != objnum) { | |
| 3638 return NULL; | |
| 3639 } | |
| 3640 word = m_syntaxParser.GetNextWord(bIsNumber); | |
| 3641 if (!bIsNumber) { | |
| 3642 return NULL; | |
| 3643 } | |
| 3644 FX_DWORD gennum = FXSYS_atoi(word); | |
| 3645 if (m_syntaxParser.GetKeyword() != FX_BSTRC("obj")) { | |
| 3646 m_syntaxParser.RestorePos(SavedPos); | |
| 3647 return NULL; | |
| 3648 } | |
| 3649 CPDF_Object* pObj = m_syntaxParser.GetObject(NULL, objnum, gennum, 0); | |
| 3650 m_syntaxParser.RestorePos(SavedPos); | |
| 3651 return pObj; | |
| 3652 } | |
| 3653 int32_t CPDF_DataAvail::IsLinearizedPDF() | |
| 3654 { | |
| 3655 FX_DWORD req_size = 1024; | |
| 3656 if (!m_pFileAvail->IsDataAvail(0, req_size)) { | |
| 3657 return PDF_UNKNOW_LINEARIZED; | |
| 3658 } | |
| 3659 if (!m_pFileRead) { | |
| 3660 return PDF_NOT_LINEARIZED; | |
| 3661 } | |
| 3662 FX_FILESIZE dwSize = m_pFileRead->GetSize(); | |
| 3663 if (dwSize < (FX_FILESIZE)req_size) { | |
| 3664 return PDF_UNKNOW_LINEARIZED; | |
| 3665 } | |
| 3666 uint8_t buffer[1024]; | 3614 uint8_t buffer[1024]; |
| 3667 m_pFileRead->ReadBlock(buffer, 0, req_size); | 3615 m_pFileRead->ReadBlock(buffer, 0, req_size); |
| 3668 if (IsLinearizedFile(buffer, req_size)) { | 3616 if (IsLinearizedFile(buffer, req_size)) { |
| 3669 return PDF_IS_LINEARIZED; | 3617 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE; |
| 3670 } | 3618 } else { |
| 3619 if (m_docStatus == PDF_DATAAVAIL_ERROR) { |
| 3620 return FALSE; |
| 3621 } |
| 3622 m_docStatus = PDF_DATAAVAIL_END; |
| 3623 } |
| 3624 return TRUE; |
| 3625 } |
| 3626 pHints->AddSegment(0, req_size); |
| 3627 return FALSE; |
| 3628 } |
| 3629 FX_BOOL CPDF_DataAvail::CheckFirstPage(IFX_DownloadHints* pHints) { |
| 3630 CPDF_Dictionary* pDict = m_pLinearized->GetDict(); |
| 3631 CPDF_Object* pEndOffSet = pDict ? pDict->GetElement(FX_BSTRC("E")) : NULL; |
| 3632 if (!pEndOffSet) { |
| 3633 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 3634 return FALSE; |
| 3635 } |
| 3636 CPDF_Object* pXRefOffset = pDict ? pDict->GetElement(FX_BSTRC("T")) : NULL; |
| 3637 if (!pXRefOffset) { |
| 3638 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 3639 return FALSE; |
| 3640 } |
| 3641 CPDF_Object* pFileLen = pDict ? pDict->GetElement(FX_BSTRC("L")) : NULL; |
| 3642 if (!pFileLen) { |
| 3643 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 3644 return FALSE; |
| 3645 } |
| 3646 FX_BOOL bNeedDownLoad = FALSE; |
| 3647 if (pEndOffSet->GetType() == PDFOBJ_NUMBER) { |
| 3648 FX_DWORD dwEnd = pEndOffSet->GetInteger(); |
| 3649 dwEnd += 512; |
| 3650 if ((FX_FILESIZE)dwEnd > m_dwFileLen) { |
| 3651 dwEnd = (FX_DWORD)m_dwFileLen; |
| 3652 } |
| 3653 int32_t iStartPos = (int32_t)(m_dwFileLen > 1024 ? 1024 : m_dwFileLen); |
| 3654 int32_t iSize = dwEnd > 1024 ? dwEnd - 1024 : 0; |
| 3655 if (!m_pFileAvail->IsDataAvail(iStartPos, iSize)) { |
| 3656 pHints->AddSegment(iStartPos, iSize); |
| 3657 bNeedDownLoad = TRUE; |
| 3658 } |
| 3659 } |
| 3660 m_dwLastXRefOffset = 0; |
| 3661 FX_FILESIZE dwFileLen = 0; |
| 3662 if (pXRefOffset->GetType() == PDFOBJ_NUMBER) { |
| 3663 m_dwLastXRefOffset = pXRefOffset->GetInteger(); |
| 3664 } |
| 3665 if (pFileLen->GetType() == PDFOBJ_NUMBER) { |
| 3666 dwFileLen = pFileLen->GetInteger(); |
| 3667 } |
| 3668 if (!m_pFileAvail->IsDataAvail(m_dwLastXRefOffset, |
| 3669 (FX_DWORD)(dwFileLen - m_dwLastXRefOffset))) { |
| 3670 if (m_docStatus == PDF_DATAAVAIL_FIRSTPAGE) { |
| 3671 FX_DWORD dwSize = (FX_DWORD)(dwFileLen - m_dwLastXRefOffset); |
| 3672 FX_FILESIZE offset = m_dwLastXRefOffset; |
| 3673 if (dwSize < 512 && dwFileLen > 512) { |
| 3674 dwSize = 512; |
| 3675 offset = dwFileLen - 512; |
| 3676 } |
| 3677 pHints->AddSegment(offset, dwSize); |
| 3678 } |
| 3679 } else { |
| 3680 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE; |
| 3681 } |
| 3682 if (!bNeedDownLoad && m_docStatus == PDF_DATAAVAIL_FIRSTPAGE_PREPARE) { |
| 3683 m_docStatus = PDF_DATAAVAIL_DONE; |
| 3684 return TRUE; |
| 3685 } |
| 3686 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE; |
| 3687 return FALSE; |
| 3688 } |
| 3689 CPDF_Object* CPDF_DataAvail::ParseIndirectObjectAt(FX_FILESIZE pos, |
| 3690 FX_DWORD objnum) { |
| 3691 FX_FILESIZE SavedPos = m_syntaxParser.SavePos(); |
| 3692 m_syntaxParser.RestorePos(pos); |
| 3693 FX_BOOL bIsNumber; |
| 3694 CFX_ByteString word = m_syntaxParser.GetNextWord(bIsNumber); |
| 3695 if (!bIsNumber) { |
| 3696 return NULL; |
| 3697 } |
| 3698 FX_DWORD parser_objnum = FXSYS_atoi(word); |
| 3699 if (objnum && parser_objnum != objnum) { |
| 3700 return NULL; |
| 3701 } |
| 3702 word = m_syntaxParser.GetNextWord(bIsNumber); |
| 3703 if (!bIsNumber) { |
| 3704 return NULL; |
| 3705 } |
| 3706 FX_DWORD gennum = FXSYS_atoi(word); |
| 3707 if (m_syntaxParser.GetKeyword() != FX_BSTRC("obj")) { |
| 3708 m_syntaxParser.RestorePos(SavedPos); |
| 3709 return NULL; |
| 3710 } |
| 3711 CPDF_Object* pObj = m_syntaxParser.GetObject(NULL, objnum, gennum, 0); |
| 3712 m_syntaxParser.RestorePos(SavedPos); |
| 3713 return pObj; |
| 3714 } |
| 3715 int32_t CPDF_DataAvail::IsLinearizedPDF() { |
| 3716 FX_DWORD req_size = 1024; |
| 3717 if (!m_pFileAvail->IsDataAvail(0, req_size)) { |
| 3718 return PDF_UNKNOW_LINEARIZED; |
| 3719 } |
| 3720 if (!m_pFileRead) { |
| 3671 return PDF_NOT_LINEARIZED; | 3721 return PDF_NOT_LINEARIZED; |
| 3672 } | 3722 } |
| 3673 FX_BOOL CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen) | 3723 FX_FILESIZE dwSize = m_pFileRead->GetSize(); |
| 3674 { | 3724 if (dwSize < (FX_FILESIZE)req_size) { |
| 3675 CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream(pData, (size_t)d
wLen, FALSE)); | 3725 return PDF_UNKNOW_LINEARIZED; |
| 3676 int32_t offset = GetHeaderOffset(file.Get()); | 3726 } |
| 3677 if (offset == -1) { | 3727 uint8_t buffer[1024]; |
| 3728 m_pFileRead->ReadBlock(buffer, 0, req_size); |
| 3729 if (IsLinearizedFile(buffer, req_size)) { |
| 3730 return PDF_IS_LINEARIZED; |
| 3731 } |
| 3732 return PDF_NOT_LINEARIZED; |
| 3733 } |
| 3734 FX_BOOL CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen) { |
| 3735 CFX_SmartPointer<IFX_FileStream> file( |
| 3736 FX_CreateMemoryStream(pData, (size_t)dwLen, FALSE)); |
| 3737 int32_t offset = GetHeaderOffset(file.Get()); |
| 3738 if (offset == -1) { |
| 3739 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 3740 return FALSE; |
| 3741 } |
| 3742 m_dwHeaderOffset = offset; |
| 3743 m_syntaxParser.InitParser(file.Get(), offset); |
| 3744 m_syntaxParser.RestorePos(m_syntaxParser.m_HeaderOffset + 9); |
| 3745 FX_BOOL bNumber = FALSE; |
| 3746 CFX_ByteString wordObjNum = m_syntaxParser.GetNextWord(bNumber); |
| 3747 if (!bNumber) { |
| 3748 return FALSE; |
| 3749 } |
| 3750 FX_DWORD objnum = FXSYS_atoi(wordObjNum); |
| 3751 if (m_pLinearized) { |
| 3752 m_pLinearized->Release(); |
| 3753 m_pLinearized = NULL; |
| 3754 } |
| 3755 m_pLinearized = |
| 3756 ParseIndirectObjectAt(m_syntaxParser.m_HeaderOffset + 9, objnum); |
| 3757 if (!m_pLinearized) { |
| 3758 return FALSE; |
| 3759 } |
| 3760 if (m_pLinearized->GetDict() && |
| 3761 m_pLinearized->GetDict()->GetElement(FX_BSTRC("Linearized"))) { |
| 3762 CPDF_Object* pLen = m_pLinearized->GetDict()->GetElement(FX_BSTRC("L")); |
| 3763 if (!pLen) { |
| 3764 return FALSE; |
| 3765 } |
| 3766 if ((FX_FILESIZE)pLen->GetInteger() != m_pFileRead->GetSize()) { |
| 3767 return FALSE; |
| 3768 } |
| 3769 m_bLinearized = TRUE; |
| 3770 CPDF_Object* pNo = m_pLinearized->GetDict()->GetElement(FX_BSTRC("P")); |
| 3771 if (pNo && pNo->GetType() == PDFOBJ_NUMBER) { |
| 3772 m_dwFirstPageNo = pNo->GetInteger(); |
| 3773 } |
| 3774 return TRUE; |
| 3775 } |
| 3776 return FALSE; |
| 3777 } |
| 3778 FX_BOOL CPDF_DataAvail::CheckEnd(IFX_DownloadHints* pHints) { |
| 3779 FX_DWORD req_pos = (FX_DWORD)(m_dwFileLen > 1024 ? m_dwFileLen - 1024 : 0); |
| 3780 FX_DWORD dwSize = (FX_DWORD)(m_dwFileLen - req_pos); |
| 3781 if (m_pFileAvail->IsDataAvail(req_pos, dwSize)) { |
| 3782 uint8_t buffer[1024]; |
| 3783 m_pFileRead->ReadBlock(buffer, req_pos, dwSize); |
| 3784 CFX_SmartPointer<IFX_FileStream> file( |
| 3785 FX_CreateMemoryStream(buffer, (size_t)dwSize, FALSE)); |
| 3786 m_syntaxParser.InitParser(file.Get(), 0); |
| 3787 m_syntaxParser.RestorePos(dwSize - 1); |
| 3788 if (m_syntaxParser.SearchWord(FX_BSTRC("startxref"), TRUE, FALSE, dwSize)) { |
| 3789 FX_BOOL bNumber; |
| 3790 m_syntaxParser.GetNextWord(bNumber); |
| 3791 CFX_ByteString xrefpos_str = m_syntaxParser.GetNextWord(bNumber); |
| 3792 if (!bNumber) { |
| 3678 m_docStatus = PDF_DATAAVAIL_ERROR; | 3793 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 3679 return FALSE; | 3794 return FALSE; |
| 3680 } | 3795 } |
| 3681 m_dwHeaderOffset = offset; | 3796 m_dwXRefOffset = (FX_FILESIZE)FXSYS_atoi64(xrefpos_str); |
| 3682 m_syntaxParser.InitParser(file.Get(), offset); | 3797 if (!m_dwXRefOffset || m_dwXRefOffset > m_dwFileLen) { |
| 3683 m_syntaxParser.RestorePos(m_syntaxParser.m_HeaderOffset + 9); | |
| 3684 FX_BOOL bNumber = FALSE; | |
| 3685 CFX_ByteString wordObjNum = m_syntaxParser.GetNextWord(bNumber); | |
| 3686 if (!bNumber) { | |
| 3687 return FALSE; | |
| 3688 } | |
| 3689 FX_DWORD objnum = FXSYS_atoi(wordObjNum); | |
| 3690 if (m_pLinearized) { | |
| 3691 m_pLinearized->Release(); | |
| 3692 m_pLinearized = NULL; | |
| 3693 } | |
| 3694 m_pLinearized = ParseIndirectObjectAt(m_syntaxParser.m_HeaderOffset + 9, obj
num); | |
| 3695 if (!m_pLinearized) { | |
| 3696 return FALSE; | |
| 3697 } | |
| 3698 if (m_pLinearized->GetDict() && m_pLinearized->GetDict()->GetElement(FX_BSTR
C("Linearized"))) { | |
| 3699 CPDF_Object *pLen = m_pLinearized->GetDict()->GetElement(FX_BSTRC("L")); | |
| 3700 if (!pLen) { | |
| 3701 return FALSE; | |
| 3702 } | |
| 3703 if ((FX_FILESIZE)pLen->GetInteger() != m_pFileRead->GetSize()) { | |
| 3704 return FALSE; | |
| 3705 } | |
| 3706 m_bLinearized = TRUE; | |
| 3707 CPDF_Object *pNo = m_pLinearized->GetDict()->GetElement(FX_BSTRC("P")); | |
| 3708 if (pNo && pNo->GetType() == PDFOBJ_NUMBER) { | |
| 3709 m_dwFirstPageNo = pNo->GetInteger(); | |
| 3710 } | |
| 3711 return TRUE; | |
| 3712 } | |
| 3713 return FALSE; | |
| 3714 } | |
| 3715 FX_BOOL CPDF_DataAvail::CheckEnd(IFX_DownloadHints* pHints) | |
| 3716 { | |
| 3717 FX_DWORD req_pos = (FX_DWORD)(m_dwFileLen > 1024 ? m_dwFileLen - 1024 : 0); | |
| 3718 FX_DWORD dwSize = (FX_DWORD)(m_dwFileLen - req_pos); | |
| 3719 if (m_pFileAvail->IsDataAvail(req_pos, dwSize)) { | |
| 3720 uint8_t buffer[1024]; | |
| 3721 m_pFileRead->ReadBlock(buffer, req_pos, dwSize); | |
| 3722 CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream(buffer, (siz
e_t)dwSize, FALSE)); | |
| 3723 m_syntaxParser.InitParser(file.Get(), 0); | |
| 3724 m_syntaxParser.RestorePos(dwSize - 1); | |
| 3725 if (m_syntaxParser.SearchWord(FX_BSTRC("startxref"), TRUE, FALSE, dwSize
)) { | |
| 3726 FX_BOOL bNumber; | |
| 3727 m_syntaxParser.GetNextWord(bNumber); | |
| 3728 CFX_ByteString xrefpos_str = m_syntaxParser.GetNextWord(bNumber); | |
| 3729 if (!bNumber) { | |
| 3730 m_docStatus = PDF_DATAAVAIL_ERROR; | |
| 3731 return FALSE; | |
| 3732 } | |
| 3733 m_dwXRefOffset = (FX_FILESIZE)FXSYS_atoi64(xrefpos_str); | |
| 3734 if (!m_dwXRefOffset || m_dwXRefOffset > m_dwFileLen) { | |
| 3735 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; | |
| 3736 return TRUE; | |
| 3737 } | |
| 3738 m_dwLastXRefOffset = m_dwXRefOffset; | |
| 3739 SetStartOffset(m_dwXRefOffset); | |
| 3740 m_docStatus = PDF_DATAAVAIL_CROSSREF; | |
| 3741 return TRUE; | |
| 3742 } | |
| 3743 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; | 3798 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; |
| 3744 return TRUE; | 3799 return TRUE; |
| 3745 } | 3800 } |
| 3746 pHints->AddSegment(req_pos, dwSize); | 3801 m_dwLastXRefOffset = m_dwXRefOffset; |
| 3747 return FALSE; | 3802 SetStartOffset(m_dwXRefOffset); |
| 3748 } | 3803 m_docStatus = PDF_DATAAVAIL_CROSSREF; |
| 3749 int32_t CPDF_DataAvail::CheckCrossRefStream(IFX_DownloadHints* pHints, FX_FILESI
ZE &xref_offset) | 3804 return TRUE; |
| 3750 { | 3805 } |
| 3751 xref_offset = 0; | 3806 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; |
| 3752 FX_DWORD req_size = (FX_DWORD)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_P
os : 512); | 3807 return TRUE; |
| 3753 if (m_pFileAvail->IsDataAvail(m_Pos, req_size)) { | 3808 } |
| 3754 int32_t iSize = (int32_t)(m_Pos + req_size - m_dwCurrentXRefSteam); | 3809 pHints->AddSegment(req_pos, dwSize); |
| 3755 CFX_BinaryBuf buf(iSize); | 3810 return FALSE; |
| 3756 uint8_t* pBuf = buf.GetBuffer(); | 3811 } |
| 3757 m_pFileRead->ReadBlock(pBuf, m_dwCurrentXRefSteam, iSize); | 3812 int32_t CPDF_DataAvail::CheckCrossRefStream(IFX_DownloadHints* pHints, |
| 3758 CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream(pBuf, (size_
t)iSize, FALSE)); | 3813 FX_FILESIZE& xref_offset) { |
| 3759 m_parser.m_Syntax.InitParser(file.Get(), 0); | 3814 xref_offset = 0; |
| 3760 FX_BOOL bNumber = FALSE; | 3815 FX_DWORD req_size = |
| 3761 CFX_ByteString objnum = m_parser.m_Syntax.GetNextWord(bNumber); | 3816 (FX_DWORD)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512); |
| 3762 if (!bNumber) { | 3817 if (m_pFileAvail->IsDataAvail(m_Pos, req_size)) { |
| 3763 return -1; | 3818 int32_t iSize = (int32_t)(m_Pos + req_size - m_dwCurrentXRefSteam); |
| 3764 } | 3819 CFX_BinaryBuf buf(iSize); |
| 3765 FX_DWORD objNum = FXSYS_atoi(objnum); | 3820 uint8_t* pBuf = buf.GetBuffer(); |
| 3766 CPDF_Object *pObj = m_parser.ParseIndirectObjectAt(NULL, 0, objNum, NULL
); | 3821 m_pFileRead->ReadBlock(pBuf, m_dwCurrentXRefSteam, iSize); |
| 3767 if (!pObj) { | 3822 CFX_SmartPointer<IFX_FileStream> file( |
| 3768 m_Pos += m_parser.m_Syntax.SavePos(); | 3823 FX_CreateMemoryStream(pBuf, (size_t)iSize, FALSE)); |
| 3769 return 0; | 3824 m_parser.m_Syntax.InitParser(file.Get(), 0); |
| 3770 } | 3825 FX_BOOL bNumber = FALSE; |
| 3771 CPDF_Dictionary* pDict = pObj->GetDict(); | 3826 CFX_ByteString objnum = m_parser.m_Syntax.GetNextWord(bNumber); |
| 3772 CPDF_Object *pName = pDict ? pDict->GetElement(FX_BSTRC("Type")) : NULL; | 3827 if (!bNumber) { |
| 3773 if (pName && pName->GetType() == PDFOBJ_NAME) { | 3828 return -1; |
| 3774 if (pName->GetString() == FX_BSTRC("XRef")) { | 3829 } |
| 3775 m_Pos += m_parser.m_Syntax.SavePos(); | 3830 FX_DWORD objNum = FXSYS_atoi(objnum); |
| 3776 xref_offset = pObj->GetDict()->GetInteger(FX_BSTRC("Prev")); | 3831 CPDF_Object* pObj = m_parser.ParseIndirectObjectAt(NULL, 0, objNum, NULL); |
| 3777 pObj->Release(); | 3832 if (!pObj) { |
| 3778 return 1; | 3833 m_Pos += m_parser.m_Syntax.SavePos(); |
| 3779 } | 3834 return 0; |
| 3780 } | 3835 } |
| 3836 CPDF_Dictionary* pDict = pObj->GetDict(); |
| 3837 CPDF_Object* pName = pDict ? pDict->GetElement(FX_BSTRC("Type")) : NULL; |
| 3838 if (pName && pName->GetType() == PDFOBJ_NAME) { |
| 3839 if (pName->GetString() == FX_BSTRC("XRef")) { |
| 3840 m_Pos += m_parser.m_Syntax.SavePos(); |
| 3841 xref_offset = pObj->GetDict()->GetInteger(FX_BSTRC("Prev")); |
| 3781 pObj->Release(); | 3842 pObj->Release(); |
| 3782 return -1; | 3843 return 1; |
| 3783 } | 3844 } |
| 3784 pHints->AddSegment(m_Pos, req_size); | 3845 } |
| 3785 return 0; | 3846 pObj->Release(); |
| 3786 } | 3847 return -1; |
| 3787 inline void CPDF_DataAvail::SetStartOffset(FX_FILESIZE dwOffset) | 3848 } |
| 3788 { | 3849 pHints->AddSegment(m_Pos, req_size); |
| 3789 m_Pos = dwOffset; | 3850 return 0; |
| 3851 } |
| 3852 inline void CPDF_DataAvail::SetStartOffset(FX_FILESIZE dwOffset) { |
| 3853 m_Pos = dwOffset; |
| 3790 } | 3854 } |
| 3791 #define MAX_WORD_BUFFER 256 | 3855 #define MAX_WORD_BUFFER 256 |
| 3792 FX_BOOL CPDF_DataAvail::GetNextToken(CFX_ByteString &token) | 3856 FX_BOOL CPDF_DataAvail::GetNextToken(CFX_ByteString& token) { |
| 3793 { | 3857 m_WordSize = 0; |
| 3794 m_WordSize = 0; | 3858 uint8_t ch; |
| 3795 uint8_t ch; | 3859 if (!GetNextChar(ch)) { |
| 3796 if (!GetNextChar(ch)) { | 3860 return FALSE; |
| 3861 } |
| 3862 uint8_t type = PDF_CharType[ch]; |
| 3863 while (1) { |
| 3864 while (type == 'W') { |
| 3865 if (!GetNextChar(ch)) { |
| 3797 return FALSE; | 3866 return FALSE; |
| 3798 } | 3867 } |
| 3799 uint8_t type = PDF_CharType[ch]; | 3868 type = PDF_CharType[ch]; |
| 3869 } |
| 3870 if (ch != '%') { |
| 3871 break; |
| 3872 } |
| 3800 while (1) { | 3873 while (1) { |
| 3801 while (type == 'W') { | 3874 if (!GetNextChar(ch)) { |
| 3802 if (!GetNextChar(ch)) { | 3875 return FALSE; |
| 3803 return FALSE; | 3876 } |
| 3804 } | 3877 if (ch == '\r' || ch == '\n') { |
| 3805 type = PDF_CharType[ch]; | 3878 break; |
| 3806 } | 3879 } |
| 3807 if (ch != '%') { | 3880 } |
| 3808 break; | 3881 type = PDF_CharType[ch]; |
| 3809 } | 3882 } |
| 3810 while (1) { | 3883 if (type == 'D') { |
| 3811 if (!GetNextChar(ch)) { | 3884 m_WordBuffer[m_WordSize++] = ch; |
| 3812 return FALSE; | 3885 if (ch == '/') { |
| 3813 } | 3886 while (1) { |
| 3814 if (ch == '\r' || ch == '\n') { | 3887 if (!GetNextChar(ch)) { |
| 3815 break; | 3888 return FALSE; |
| 3816 } | |
| 3817 } | 3889 } |
| 3818 type = PDF_CharType[ch]; | 3890 type = PDF_CharType[ch]; |
| 3819 } | 3891 if (type != 'R' && type != 'N') { |
| 3820 if (type == 'D') { | 3892 m_Pos--; |
| 3893 CFX_ByteString ret(m_WordBuffer, m_WordSize); |
| 3894 token = ret; |
| 3895 return TRUE; |
| 3896 } |
| 3897 if (m_WordSize < MAX_WORD_BUFFER) { |
| 3898 m_WordBuffer[m_WordSize++] = ch; |
| 3899 } |
| 3900 } |
| 3901 } else if (ch == '<') { |
| 3902 if (!GetNextChar(ch)) { |
| 3903 return FALSE; |
| 3904 } |
| 3905 if (ch == '<') { |
| 3821 m_WordBuffer[m_WordSize++] = ch; | 3906 m_WordBuffer[m_WordSize++] = ch; |
| 3822 if (ch == '/') { | 3907 } else { |
| 3823 while (1) { | 3908 m_Pos--; |
| 3824 if (!GetNextChar(ch)) { | 3909 } |
| 3825 return FALSE; | 3910 } else if (ch == '>') { |
| 3826 } | 3911 if (!GetNextChar(ch)) { |
| 3827 type = PDF_CharType[ch]; | 3912 return FALSE; |
| 3828 if (type != 'R' && type != 'N') { | 3913 } |
| 3829 m_Pos --; | 3914 if (ch == '>') { |
| 3830 CFX_ByteString ret(m_WordBuffer, m_WordSize); | 3915 m_WordBuffer[m_WordSize++] = ch; |
| 3831 token = ret; | 3916 } else { |
| 3832 return TRUE; | 3917 m_Pos--; |
| 3833 } | 3918 } |
| 3834 if (m_WordSize < MAX_WORD_BUFFER) { | |
| 3835 m_WordBuffer[m_WordSize++] = ch; | |
| 3836 } | |
| 3837 } | |
| 3838 } else if (ch == '<') { | |
| 3839 if (!GetNextChar(ch)) { | |
| 3840 return FALSE; | |
| 3841 } | |
| 3842 if (ch == '<') { | |
| 3843 m_WordBuffer[m_WordSize++] = ch; | |
| 3844 } else { | |
| 3845 m_Pos --; | |
| 3846 } | |
| 3847 } else if (ch == '>') { | |
| 3848 if (!GetNextChar(ch)) { | |
| 3849 return FALSE; | |
| 3850 } | |
| 3851 if (ch == '>') { | |
| 3852 m_WordBuffer[m_WordSize++] = ch; | |
| 3853 } else { | |
| 3854 m_Pos --; | |
| 3855 } | |
| 3856 } | |
| 3857 CFX_ByteString ret(m_WordBuffer, m_WordSize); | |
| 3858 token = ret; | |
| 3859 return TRUE; | |
| 3860 } | |
| 3861 while (1) { | |
| 3862 if (m_WordSize < MAX_WORD_BUFFER) { | |
| 3863 m_WordBuffer[m_WordSize++] = ch; | |
| 3864 } | |
| 3865 if (!GetNextChar(ch)) { | |
| 3866 return FALSE; | |
| 3867 } | |
| 3868 type = PDF_CharType[ch]; | |
| 3869 if (type == 'D' || type == 'W') { | |
| 3870 m_Pos --; | |
| 3871 break; | |
| 3872 } | |
| 3873 } | 3919 } |
| 3874 CFX_ByteString ret(m_WordBuffer, m_WordSize); | 3920 CFX_ByteString ret(m_WordBuffer, m_WordSize); |
| 3875 token = ret; | 3921 token = ret; |
| 3876 return TRUE; | 3922 return TRUE; |
| 3877 } | 3923 } |
| 3878 FX_BOOL CPDF_DataAvail::GetNextChar(uint8_t &ch) | 3924 while (1) { |
| 3879 { | 3925 if (m_WordSize < MAX_WORD_BUFFER) { |
| 3880 FX_FILESIZE pos = m_Pos; | 3926 m_WordBuffer[m_WordSize++] = ch; |
| 3881 if (pos >= m_dwFileLen) { | 3927 } |
| 3928 if (!GetNextChar(ch)) { |
| 3929 return FALSE; |
| 3930 } |
| 3931 type = PDF_CharType[ch]; |
| 3932 if (type == 'D' || type == 'W') { |
| 3933 m_Pos--; |
| 3934 break; |
| 3935 } |
| 3936 } |
| 3937 CFX_ByteString ret(m_WordBuffer, m_WordSize); |
| 3938 token = ret; |
| 3939 return TRUE; |
| 3940 } |
| 3941 FX_BOOL CPDF_DataAvail::GetNextChar(uint8_t& ch) { |
| 3942 FX_FILESIZE pos = m_Pos; |
| 3943 if (pos >= m_dwFileLen) { |
| 3944 return FALSE; |
| 3945 } |
| 3946 if (m_bufferOffset >= pos || |
| 3947 (FX_FILESIZE)(m_bufferOffset + m_bufferSize) <= pos) { |
| 3948 FX_FILESIZE read_pos = pos; |
| 3949 FX_DWORD read_size = 512; |
| 3950 if ((FX_FILESIZE)read_size > m_dwFileLen) { |
| 3951 read_size = (FX_DWORD)m_dwFileLen; |
| 3952 } |
| 3953 if ((FX_FILESIZE)(read_pos + read_size) > m_dwFileLen) { |
| 3954 read_pos = m_dwFileLen - read_size; |
| 3955 } |
| 3956 if (!m_pFileRead->ReadBlock(m_bufferData, read_pos, read_size)) { |
| 3957 return FALSE; |
| 3958 } |
| 3959 m_bufferOffset = read_pos; |
| 3960 m_bufferSize = read_size; |
| 3961 } |
| 3962 ch = m_bufferData[pos - m_bufferOffset]; |
| 3963 m_Pos++; |
| 3964 return TRUE; |
| 3965 } |
| 3966 FX_BOOL CPDF_DataAvail::CheckCrossRefItem(IFX_DownloadHints* pHints) { |
| 3967 int32_t iSize = 0; |
| 3968 CFX_ByteString token; |
| 3969 while (1) { |
| 3970 if (!GetNextToken(token)) { |
| 3971 iSize = (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512); |
| 3972 pHints->AddSegment(m_Pos, iSize); |
| 3973 return FALSE; |
| 3974 } |
| 3975 if (token == "trailer") { |
| 3976 m_dwTrailerOffset = m_Pos; |
| 3977 m_docStatus = PDF_DATAAVAIL_TRAILER; |
| 3978 return TRUE; |
| 3979 } |
| 3980 } |
| 3981 } |
| 3982 FX_BOOL CPDF_DataAvail::CheckAllCrossRefStream(IFX_DownloadHints* pHints) { |
| 3983 FX_FILESIZE xref_offset = 0; |
| 3984 int32_t nRet = CheckCrossRefStream(pHints, xref_offset); |
| 3985 if (nRet == 1) { |
| 3986 if (!xref_offset) { |
| 3987 m_docStatus = PDF_DATAAVAIL_LOADALLCRSOSSREF; |
| 3988 } else { |
| 3989 m_dwCurrentXRefSteam = xref_offset; |
| 3990 m_Pos = xref_offset; |
| 3991 } |
| 3992 return TRUE; |
| 3993 } |
| 3994 if (nRet == -1) { |
| 3995 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 3996 } |
| 3997 return FALSE; |
| 3998 } |
| 3999 FX_BOOL CPDF_DataAvail::CheckCrossRef(IFX_DownloadHints* pHints) { |
| 4000 int32_t iSize = 0; |
| 4001 CFX_ByteString token; |
| 4002 if (!GetNextToken(token)) { |
| 4003 iSize = (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512); |
| 4004 pHints->AddSegment(m_Pos, iSize); |
| 4005 return FALSE; |
| 4006 } |
| 4007 if (token == "xref") { |
| 4008 m_CrossOffset.InsertAt(0, m_dwXRefOffset); |
| 4009 while (1) { |
| 4010 if (!GetNextToken(token)) { |
| 4011 iSize = |
| 4012 (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512); |
| 4013 pHints->AddSegment(m_Pos, iSize); |
| 4014 m_docStatus = PDF_DATAAVAIL_CROSSREF_ITEM; |
| 3882 return FALSE; | 4015 return FALSE; |
| 3883 } | 4016 } |
| 3884 if (m_bufferOffset >= pos || (FX_FILESIZE)(m_bufferOffset + m_bufferSize) <=
pos) { | 4017 if (token == "trailer") { |
| 3885 FX_FILESIZE read_pos = pos; | 4018 m_dwTrailerOffset = m_Pos; |
| 3886 FX_DWORD read_size = 512; | 4019 m_docStatus = PDF_DATAAVAIL_TRAILER; |
| 3887 if ((FX_FILESIZE)read_size > m_dwFileLen) { | 4020 return TRUE; |
| 3888 read_size = (FX_DWORD)m_dwFileLen; | 4021 } |
| 3889 } | 4022 } |
| 3890 if ((FX_FILESIZE)(read_pos + read_size) > m_dwFileLen) { | 4023 } else { |
| 3891 read_pos = m_dwFileLen - read_size; | 4024 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; |
| 3892 } | |
| 3893 if (!m_pFileRead->ReadBlock(m_bufferData, read_pos, read_size)) { | |
| 3894 return FALSE; | |
| 3895 } | |
| 3896 m_bufferOffset = read_pos; | |
| 3897 m_bufferSize = read_size; | |
| 3898 } | |
| 3899 ch = m_bufferData[pos - m_bufferOffset]; | |
| 3900 m_Pos ++; | |
| 3901 return TRUE; | 4025 return TRUE; |
| 3902 } | 4026 } |
| 3903 FX_BOOL CPDF_DataAvail::CheckCrossRefItem(IFX_DownloadHints *pHints) | 4027 return FALSE; |
| 3904 { | 4028 } |
| 3905 int32_t iSize = 0; | 4029 FX_BOOL CPDF_DataAvail::CheckTrailerAppend(IFX_DownloadHints* pHints) { |
| 3906 CFX_ByteString token; | 4030 if (m_Pos < m_dwFileLen) { |
| 3907 while (1) { | 4031 FX_FILESIZE dwAppendPos = m_Pos + m_syntaxParser.SavePos(); |
| 3908 if (!GetNextToken(token)) { | 4032 int32_t iSize = (int32_t)( |
| 3909 iSize = (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos :
512); | 4033 dwAppendPos + 512 > m_dwFileLen ? m_dwFileLen - dwAppendPos : 512); |
| 3910 pHints->AddSegment(m_Pos, iSize); | 4034 if (!m_pFileAvail->IsDataAvail(dwAppendPos, iSize)) { |
| 3911 return FALSE; | 4035 pHints->AddSegment(dwAppendPos, iSize); |
| 3912 } | 4036 return FALSE; |
| 3913 if (token == "trailer") { | 4037 } |
| 3914 m_dwTrailerOffset = m_Pos; | 4038 } |
| 3915 m_docStatus = PDF_DATAAVAIL_TRAILER; | 4039 if (m_dwPrevXRefOffset) { |
| 3916 return TRUE; | 4040 SetStartOffset(m_dwPrevXRefOffset); |
| 3917 } | 4041 m_docStatus = PDF_DATAAVAIL_CROSSREF; |
| 3918 } | 4042 } else { |
| 3919 } | 4043 m_docStatus = PDF_DATAAVAIL_LOADALLCRSOSSREF; |
| 3920 FX_BOOL CPDF_DataAvail::CheckAllCrossRefStream(IFX_DownloadHints *pHints) | 4044 } |
| 3921 { | 4045 return TRUE; |
| 3922 FX_FILESIZE xref_offset = 0; | 4046 } |
| 3923 int32_t nRet = CheckCrossRefStream(pHints, xref_offset); | 4047 FX_BOOL CPDF_DataAvail::CheckTrailer(IFX_DownloadHints* pHints) { |
| 3924 if (nRet == 1) { | 4048 int32_t iTrailerSize = |
| 3925 if (!xref_offset) { | 4049 (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512); |
| 3926 m_docStatus = PDF_DATAAVAIL_LOADALLCRSOSSREF; | 4050 if (m_pFileAvail->IsDataAvail(m_Pos, iTrailerSize)) { |
| 3927 } else { | 4051 int32_t iSize = (int32_t)(m_Pos + iTrailerSize - m_dwTrailerOffset); |
| 3928 m_dwCurrentXRefSteam = xref_offset; | 4052 CFX_BinaryBuf buf(iSize); |
| 3929 m_Pos = xref_offset; | 4053 uint8_t* pBuf = buf.GetBuffer(); |
| 3930 } | 4054 if (!pBuf) { |
| 3931 return TRUE; | 4055 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 3932 } | 4056 return FALSE; |
| 3933 if (nRet == -1) { | 4057 } |
| 3934 m_docStatus = PDF_DATAAVAIL_ERROR; | 4058 if (!m_pFileRead->ReadBlock(pBuf, m_dwTrailerOffset, iSize)) { |
| 3935 } | 4059 return FALSE; |
| 3936 return FALSE; | 4060 } |
| 3937 } | 4061 CFX_SmartPointer<IFX_FileStream> file( |
| 3938 FX_BOOL CPDF_DataAvail::CheckCrossRef(IFX_DownloadHints* pHints) | 4062 FX_CreateMemoryStream(pBuf, (size_t)iSize, FALSE)); |
| 3939 { | 4063 m_syntaxParser.InitParser(file.Get(), 0); |
| 3940 int32_t iSize = 0; | 4064 CPDF_Object* pTrailer = m_syntaxParser.GetObject(NULL, 0, 0, 0); |
| 3941 CFX_ByteString token; | 4065 if (!pTrailer) { |
| 3942 if (!GetNextToken(token)) { | 4066 m_Pos += m_syntaxParser.SavePos(); |
| 3943 iSize = (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512)
; | 4067 pHints->AddSegment(m_Pos, iTrailerSize); |
| 3944 pHints->AddSegment(m_Pos, iSize); | 4068 return FALSE; |
| 3945 return FALSE; | 4069 } |
| 3946 } | 4070 if (pTrailer->GetType() != PDFOBJ_DICTIONARY) { |
| 3947 if (token == "xref") { | 4071 return FALSE; |
| 3948 m_CrossOffset.InsertAt(0, m_dwXRefOffset); | 4072 } |
| 3949 while (1) { | 4073 CPDF_Dictionary* pTrailerDict = pTrailer->GetDict(); |
| 3950 if (!GetNextToken(token)) { | 4074 if (pTrailerDict) { |
| 3951 iSize = (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Po
s : 512); | 4075 CPDF_Object* pEncrypt = pTrailerDict->GetElement("Encrypt"); |
| 3952 pHints->AddSegment(m_Pos, iSize); | 4076 if (pEncrypt && pEncrypt->GetType() == PDFOBJ_REFERENCE) { |
| 3953 m_docStatus = PDF_DATAAVAIL_CROSSREF_ITEM; | |
| 3954 return FALSE; | |
| 3955 } | |
| 3956 if (token == "trailer") { | |
| 3957 m_dwTrailerOffset = m_Pos; | |
| 3958 m_docStatus = PDF_DATAAVAIL_TRAILER; | |
| 3959 return TRUE; | |
| 3960 } | |
| 3961 } | |
| 3962 } else { | |
| 3963 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; | 4077 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; |
| 3964 return TRUE; | |
| 3965 } | |
| 3966 return FALSE; | |
| 3967 } | |
| 3968 FX_BOOL CPDF_DataAvail::CheckTrailerAppend(IFX_DownloadHints* pHints) | |
| 3969 { | |
| 3970 if (m_Pos < m_dwFileLen) { | |
| 3971 FX_FILESIZE dwAppendPos = m_Pos + m_syntaxParser.SavePos(); | |
| 3972 int32_t iSize = (int32_t)(dwAppendPos + 512 > m_dwFileLen ? m_dwFileLen
- dwAppendPos : 512); | |
| 3973 if (!m_pFileAvail->IsDataAvail(dwAppendPos, iSize)) { | |
| 3974 pHints->AddSegment(dwAppendPos, iSize); | |
| 3975 return FALSE; | |
| 3976 } | |
| 3977 } | |
| 3978 if (m_dwPrevXRefOffset) { | |
| 3979 SetStartOffset(m_dwPrevXRefOffset); | |
| 3980 m_docStatus = PDF_DATAAVAIL_CROSSREF; | |
| 3981 } else { | |
| 3982 m_docStatus = PDF_DATAAVAIL_LOADALLCRSOSSREF; | |
| 3983 } | |
| 3984 return TRUE; | |
| 3985 } | |
| 3986 FX_BOOL CPDF_DataAvail::CheckTrailer(IFX_DownloadHints* pHints) | |
| 3987 { | |
| 3988 int32_t iTrailerSize = (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m
_Pos : 512); | |
| 3989 if (m_pFileAvail->IsDataAvail(m_Pos, iTrailerSize)) { | |
| 3990 int32_t iSize = (int32_t)(m_Pos + iTrailerSize - m_dwTrailerOffset); | |
| 3991 CFX_BinaryBuf buf(iSize); | |
| 3992 uint8_t* pBuf = buf.GetBuffer(); | |
| 3993 if (!pBuf) { | |
| 3994 m_docStatus = PDF_DATAAVAIL_ERROR; | |
| 3995 return FALSE; | |
| 3996 } | |
| 3997 if (!m_pFileRead->ReadBlock(pBuf, m_dwTrailerOffset, iSize)) { | |
| 3998 return FALSE; | |
| 3999 } | |
| 4000 CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream(pBuf, (size_
t)iSize, FALSE)); | |
| 4001 m_syntaxParser.InitParser(file.Get(), 0); | |
| 4002 CPDF_Object *pTrailer = m_syntaxParser.GetObject(NULL, 0, 0, 0); | |
| 4003 if (!pTrailer) { | |
| 4004 m_Pos += m_syntaxParser.SavePos(); | |
| 4005 pHints->AddSegment(m_Pos, iTrailerSize); | |
| 4006 return FALSE; | |
| 4007 } | |
| 4008 if (pTrailer->GetType() != PDFOBJ_DICTIONARY) { | |
| 4009 return FALSE; | |
| 4010 } | |
| 4011 CPDF_Dictionary *pTrailerDict = pTrailer->GetDict(); | |
| 4012 if (pTrailerDict) { | |
| 4013 CPDF_Object *pEncrypt = pTrailerDict->GetElement("Encrypt"); | |
| 4014 if (pEncrypt && pEncrypt->GetType() == PDFOBJ_REFERENCE) { | |
| 4015 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; | |
| 4016 pTrailer->Release(); | |
| 4017 return TRUE; | |
| 4018 } | |
| 4019 } | |
| 4020 FX_DWORD xrefpos = GetDirectInteger(pTrailer->GetDict(), FX_BSTRC("Prev"
)); | |
| 4021 if (xrefpos) { | |
| 4022 m_dwPrevXRefOffset = GetDirectInteger(pTrailer->GetDict(), FX_BSTRC(
"XRefStm")); | |
| 4023 pTrailer->Release(); | |
| 4024 if (m_dwPrevXRefOffset) { | |
| 4025 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; | |
| 4026 } else { | |
| 4027 m_dwPrevXRefOffset = xrefpos; | |
| 4028 if (m_dwPrevXRefOffset >= m_dwFileLen) { | |
| 4029 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; | |
| 4030 } else { | |
| 4031 SetStartOffset(m_dwPrevXRefOffset); | |
| 4032 m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND; | |
| 4033 } | |
| 4034 } | |
| 4035 return TRUE; | |
| 4036 } | |
| 4037 m_dwPrevXRefOffset = 0; | |
| 4038 m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND; | |
| 4039 pTrailer->Release(); | 4078 pTrailer->Release(); |
| 4040 return TRUE; | 4079 return TRUE; |
| 4041 } | 4080 } |
| 4042 pHints->AddSegment(m_Pos, iTrailerSize); | 4081 } |
| 4043 return FALSE; | 4082 FX_DWORD xrefpos = GetDirectInteger(pTrailer->GetDict(), FX_BSTRC("Prev")); |
| 4044 } | 4083 if (xrefpos) { |
| 4045 FX_BOOL CPDF_DataAvail::CheckPage(int32_t iPage, IFX_DownloadHints* pHints) | 4084 m_dwPrevXRefOffset = |
| 4046 { | 4085 GetDirectInteger(pTrailer->GetDict(), FX_BSTRC("XRefStm")); |
| 4047 while (TRUE) { | 4086 pTrailer->Release(); |
| 4048 switch (m_docStatus) { | 4087 if (m_dwPrevXRefOffset) { |
| 4049 case PDF_DATAAVAIL_PAGETREE: | 4088 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; |
| 4050 if (!LoadDocPages(pHints)) { | 4089 } else { |
| 4051 return FALSE; | 4090 m_dwPrevXRefOffset = xrefpos; |
| 4052 } | 4091 if (m_dwPrevXRefOffset >= m_dwFileLen) { |
| 4053 break; | 4092 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; |
| 4054 case PDF_DATAAVAIL_PAGE: | 4093 } else { |
| 4055 if (!LoadDocPage(iPage, pHints)) { | 4094 SetStartOffset(m_dwPrevXRefOffset); |
| 4056 return FALSE; | 4095 m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND; |
| 4057 } | 4096 } |
| 4058 break; | 4097 } |
| 4059 case PDF_DATAAVAIL_ERROR: | 4098 return TRUE; |
| 4060 return LoadAllFile(pHints); | 4099 } |
| 4061 default: | 4100 m_dwPrevXRefOffset = 0; |
| 4062 m_bPagesTreeLoad = TRUE; | 4101 m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND; |
| 4063 m_bPagesLoad = TRUE; | 4102 pTrailer->Release(); |
| 4064 m_bCurPageDictLoadOK = TRUE; | 4103 return TRUE; |
| 4065 m_docStatus = PDF_DATAAVAIL_PAGE; | 4104 } |
| 4066 return TRUE; | 4105 pHints->AddSegment(m_Pos, iTrailerSize); |
| 4067 } | 4106 return FALSE; |
| 4068 } | 4107 } |
| 4069 } | 4108 FX_BOOL CPDF_DataAvail::CheckPage(int32_t iPage, IFX_DownloadHints* pHints) { |
| 4070 FX_BOOL»CPDF_DataAvail::CheckArrayPageNode(FX_DWORD dwPageNo, CPDF_PageNode *pPa
geNode, IFX_DownloadHints* pHints) | 4109 while (TRUE) { |
| 4071 { | 4110 switch (m_docStatus) { |
| 4072 FX_BOOL bExist = FALSE; | 4111 case PDF_DATAAVAIL_PAGETREE: |
| 4073 CPDF_Object *pPages = GetObject(dwPageNo, pHints, &bExist); | 4112 if (!LoadDocPages(pHints)) { |
| 4074 if (!bExist) { | 4113 return FALSE; |
| 4075 m_docStatus = PDF_DATAAVAIL_ERROR; | 4114 } |
| 4076 return FALSE; | 4115 break; |
| 4077 } | 4116 case PDF_DATAAVAIL_PAGE: |
| 4078 if (!pPages) { | 4117 if (!LoadDocPage(iPage, pHints)) { |
| 4079 if (m_docStatus == PDF_DATAAVAIL_ERROR) { | 4118 return FALSE; |
| 4080 m_docStatus = PDF_DATAAVAIL_ERROR; | 4119 } |
| 4081 return FALSE; | 4120 break; |
| 4082 } | 4121 case PDF_DATAAVAIL_ERROR: |
| 4083 return FALSE; | 4122 return LoadAllFile(pHints); |
| 4084 } | 4123 default: |
| 4085 if (pPages->GetType() != PDFOBJ_ARRAY) { | 4124 m_bPagesTreeLoad = TRUE; |
| 4086 pPages->Release(); | 4125 m_bPagesLoad = TRUE; |
| 4087 m_docStatus = PDF_DATAAVAIL_ERROR; | 4126 m_bCurPageDictLoadOK = TRUE; |
| 4088 return FALSE; | 4127 m_docStatus = PDF_DATAAVAIL_PAGE; |
| 4089 } | 4128 return TRUE; |
| 4129 } |
| 4130 } |
| 4131 } |
| 4132 FX_BOOL CPDF_DataAvail::CheckArrayPageNode(FX_DWORD dwPageNo, |
| 4133 CPDF_PageNode* pPageNode, |
| 4134 IFX_DownloadHints* pHints) { |
| 4135 FX_BOOL bExist = FALSE; |
| 4136 CPDF_Object* pPages = GetObject(dwPageNo, pHints, &bExist); |
| 4137 if (!bExist) { |
| 4138 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 4139 return FALSE; |
| 4140 } |
| 4141 if (!pPages) { |
| 4142 if (m_docStatus == PDF_DATAAVAIL_ERROR) { |
| 4143 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 4144 return FALSE; |
| 4145 } |
| 4146 return FALSE; |
| 4147 } |
| 4148 if (pPages->GetType() != PDFOBJ_ARRAY) { |
| 4149 pPages->Release(); |
| 4150 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 4151 return FALSE; |
| 4152 } |
| 4153 pPageNode->m_type = PDF_PAGENODE_PAGES; |
| 4154 CPDF_Array* pArray = (CPDF_Array*)pPages; |
| 4155 for (FX_DWORD i = 0; i < pArray->GetCount(); ++i) { |
| 4156 CPDF_Object* pKid = (CPDF_Object*)pArray->GetElement(i); |
| 4157 if (!pKid || pKid->GetType() != PDFOBJ_REFERENCE) { |
| 4158 continue; |
| 4159 } |
| 4160 CPDF_PageNode* pNode = new CPDF_PageNode(); |
| 4161 pPageNode->m_childNode.Add(pNode); |
| 4162 pNode->m_dwPageNo = ((CPDF_Reference*)pKid)->GetRefObjNum(); |
| 4163 } |
| 4164 pPages->Release(); |
| 4165 return TRUE; |
| 4166 } |
| 4167 FX_BOOL CPDF_DataAvail::CheckUnkownPageNode(FX_DWORD dwPageNo, |
| 4168 CPDF_PageNode* pPageNode, |
| 4169 IFX_DownloadHints* pHints) { |
| 4170 FX_BOOL bExist = FALSE; |
| 4171 CPDF_Object* pPage = GetObject(dwPageNo, pHints, &bExist); |
| 4172 if (!bExist) { |
| 4173 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 4174 return FALSE; |
| 4175 } |
| 4176 if (!pPage) { |
| 4177 if (m_docStatus == PDF_DATAAVAIL_ERROR) { |
| 4178 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 4179 return FALSE; |
| 4180 } |
| 4181 return FALSE; |
| 4182 } |
| 4183 if (pPage->GetType() == PDFOBJ_ARRAY) { |
| 4184 pPageNode->m_dwPageNo = dwPageNo; |
| 4185 pPageNode->m_type = PDF_PAGENODE_ARRAY; |
| 4186 pPage->Release(); |
| 4187 return TRUE; |
| 4188 } |
| 4189 if (pPage->GetType() != PDFOBJ_DICTIONARY) { |
| 4190 pPage->Release(); |
| 4191 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 4192 return FALSE; |
| 4193 } |
| 4194 pPageNode->m_dwPageNo = dwPageNo; |
| 4195 CPDF_Dictionary* pDict = pPage->GetDict(); |
| 4196 CFX_ByteString type = |
| 4197 pDict ? pDict->GetString(FX_BSTRC("Type")) : CFX_ByteString(); |
| 4198 if (type == FX_BSTRC("Pages")) { |
| 4090 pPageNode->m_type = PDF_PAGENODE_PAGES; | 4199 pPageNode->m_type = PDF_PAGENODE_PAGES; |
| 4091 CPDF_Array* pArray = (CPDF_Array*)pPages; | 4200 CPDF_Object* pKids = pDict->GetElement(FX_BSTRC("Kids")); |
| 4092 for (FX_DWORD i = 0; i < pArray->GetCount(); ++i) { | 4201 if (!pKids) { |
| 4093 CPDF_Object *pKid = (CPDF_Object *)pArray->GetElement(i); | 4202 m_docStatus = PDF_DATAAVAIL_PAGE; |
| 4094 if (!pKid || pKid->GetType() != PDFOBJ_REFERENCE) { | 4203 return TRUE; |
| 4204 } |
| 4205 switch (pKids->GetType()) { |
| 4206 case PDFOBJ_REFERENCE: { |
| 4207 CPDF_Reference* pKid = (CPDF_Reference*)pKids; |
| 4208 CPDF_PageNode* pNode = new CPDF_PageNode(); |
| 4209 pPageNode->m_childNode.Add(pNode); |
| 4210 pNode->m_dwPageNo = pKid->GetRefObjNum(); |
| 4211 } break; |
| 4212 case PDFOBJ_ARRAY: { |
| 4213 CPDF_Array* pKidsArray = (CPDF_Array*)pKids; |
| 4214 for (FX_DWORD i = 0; i < pKidsArray->GetCount(); ++i) { |
| 4215 CPDF_Object* pKid = (CPDF_Object*)pKidsArray->GetElement(i); |
| 4216 if (!pKid || pKid->GetType() != PDFOBJ_REFERENCE) { |
| 4095 continue; | 4217 continue; |
| 4096 } | 4218 } |
| 4097 CPDF_PageNode *pNode = new CPDF_PageNode(); | 4219 CPDF_PageNode* pNode = new CPDF_PageNode(); |
| 4098 pPageNode->m_childNode.Add(pNode); | 4220 pPageNode->m_childNode.Add(pNode); |
| 4099 pNode->m_dwPageNo = ((CPDF_Reference*)pKid)->GetRefObjNum(); | 4221 pNode->m_dwPageNo = ((CPDF_Reference*)pKid)->GetRefObjNum(); |
| 4100 } | 4222 } |
| 4223 } break; |
| 4224 default: |
| 4225 break; |
| 4226 } |
| 4227 } else if (type == FX_BSTRC("Page")) { |
| 4228 pPageNode->m_type = PDF_PAGENODE_PAGE; |
| 4229 } else { |
| 4230 pPage->Release(); |
| 4231 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 4232 return FALSE; |
| 4233 } |
| 4234 pPage->Release(); |
| 4235 return TRUE; |
| 4236 } |
| 4237 FX_BOOL CPDF_DataAvail::CheckPageNode(CPDF_PageNode& pageNodes, |
| 4238 int32_t iPage, |
| 4239 int32_t& iCount, |
| 4240 IFX_DownloadHints* pHints) { |
| 4241 int32_t iSize = pageNodes.m_childNode.GetSize(); |
| 4242 if (iSize <= 0 || iPage >= iSize) { |
| 4243 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 4244 return FALSE; |
| 4245 } |
| 4246 for (int32_t i = 0; i < iSize; ++i) { |
| 4247 CPDF_PageNode* pNode = (CPDF_PageNode*)pageNodes.m_childNode.GetAt(i); |
| 4248 if (!pNode) { |
| 4249 continue; |
| 4250 } |
| 4251 switch (pNode->m_type) { |
| 4252 case PDF_PAGENODE_UNKOWN: |
| 4253 if (!CheckUnkownPageNode(pNode->m_dwPageNo, pNode, pHints)) { |
| 4254 return FALSE; |
| 4255 } |
| 4256 --i; |
| 4257 break; |
| 4258 case PDF_PAGENODE_PAGE: |
| 4259 iCount++; |
| 4260 if (iPage == iCount && m_pDocument) { |
| 4261 m_pDocument->m_PageList.SetAt(iPage, pNode->m_dwPageNo); |
| 4262 } |
| 4263 break; |
| 4264 case PDF_PAGENODE_PAGES: |
| 4265 if (!CheckPageNode(*pNode, iPage, iCount, pHints)) { |
| 4266 return FALSE; |
| 4267 } |
| 4268 break; |
| 4269 case PDF_PAGENODE_ARRAY: |
| 4270 if (!CheckArrayPageNode(pNode->m_dwPageNo, pNode, pHints)) { |
| 4271 return FALSE; |
| 4272 } |
| 4273 --i; |
| 4274 break; |
| 4275 } |
| 4276 if (iPage == iCount) { |
| 4277 m_docStatus = PDF_DATAAVAIL_DONE; |
| 4278 return TRUE; |
| 4279 } |
| 4280 } |
| 4281 return TRUE; |
| 4282 } |
| 4283 FX_BOOL CPDF_DataAvail::LoadDocPage(int32_t iPage, IFX_DownloadHints* pHints) { |
| 4284 if (m_pDocument->GetPageCount() <= iPage || |
| 4285 m_pDocument->m_PageList.GetAt(iPage)) { |
| 4286 m_docStatus = PDF_DATAAVAIL_DONE; |
| 4287 return TRUE; |
| 4288 } |
| 4289 if (m_pageNodes.m_type == PDF_PAGENODE_PAGE) { |
| 4290 if (iPage == 0) { |
| 4291 m_docStatus = PDF_DATAAVAIL_DONE; |
| 4292 return TRUE; |
| 4293 } |
| 4294 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 4295 return TRUE; |
| 4296 } |
| 4297 int32_t iCount = -1; |
| 4298 return CheckPageNode(m_pageNodes, iPage, iCount, pHints); |
| 4299 } |
| 4300 FX_BOOL CPDF_DataAvail::CheckPageCount(IFX_DownloadHints* pHints) { |
| 4301 FX_BOOL bExist = FALSE; |
| 4302 CPDF_Object* pPages = GetObject(m_PagesObjNum, pHints, &bExist); |
| 4303 if (!bExist) { |
| 4304 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 4305 return FALSE; |
| 4306 } |
| 4307 if (!pPages) { |
| 4308 return FALSE; |
| 4309 } |
| 4310 CPDF_Dictionary* pPagesDict = pPages->GetDict(); |
| 4311 if (!pPagesDict) { |
| 4312 pPages->Release(); |
| 4313 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 4314 return FALSE; |
| 4315 } |
| 4316 if (!pPagesDict->KeyExist(FX_BSTRC("Kids"))) { |
| 4101 pPages->Release(); | 4317 pPages->Release(); |
| 4102 return TRUE; | 4318 return TRUE; |
| 4103 } | 4319 } |
| 4104 FX_BOOL CPDF_DataAvail::CheckUnkownPageNode(FX_DWORD dwPageNo, CPDF_PageNode *pP
ageNode, IFX_DownloadHints* pHints) | 4320 int count = pPagesDict->GetInteger(FX_BSTRC("Count")); |
| 4105 { | 4321 if (count > 0) { |
| 4106 FX_BOOL bExist = FALSE; | 4322 pPages->Release(); |
| 4107 CPDF_Object *pPage = GetObject(dwPageNo, pHints, &bExist); | |
| 4108 if (!bExist) { | |
| 4109 m_docStatus = PDF_DATAAVAIL_ERROR; | |
| 4110 return FALSE; | |
| 4111 } | |
| 4112 if (!pPage) { | |
| 4113 if (m_docStatus == PDF_DATAAVAIL_ERROR) { | |
| 4114 m_docStatus = PDF_DATAAVAIL_ERROR; | |
| 4115 return FALSE; | |
| 4116 } | |
| 4117 return FALSE; | |
| 4118 } | |
| 4119 if (pPage->GetType() == PDFOBJ_ARRAY) { | |
| 4120 pPageNode->m_dwPageNo = dwPageNo; | |
| 4121 pPageNode->m_type = PDF_PAGENODE_ARRAY; | |
| 4122 pPage->Release(); | |
| 4123 return TRUE; | |
| 4124 } | |
| 4125 if (pPage->GetType() != PDFOBJ_DICTIONARY) { | |
| 4126 pPage->Release(); | |
| 4127 m_docStatus = PDF_DATAAVAIL_ERROR; | |
| 4128 return FALSE; | |
| 4129 } | |
| 4130 pPageNode->m_dwPageNo = dwPageNo; | |
| 4131 CPDF_Dictionary* pDict = pPage->GetDict(); | |
| 4132 CFX_ByteString type = pDict ? pDict->GetString(FX_BSTRC("Type")) : CFX_ByteS
tring(); | |
| 4133 if (type == FX_BSTRC("Pages")) { | |
| 4134 pPageNode->m_type = PDF_PAGENODE_PAGES; | |
| 4135 CPDF_Object *pKids = pDict->GetElement(FX_BSTRC("Kids")); | |
| 4136 if (!pKids) { | |
| 4137 m_docStatus = PDF_DATAAVAIL_PAGE; | |
| 4138 return TRUE; | |
| 4139 } | |
| 4140 switch (pKids->GetType()) { | |
| 4141 case PDFOBJ_REFERENCE: { | |
| 4142 CPDF_Reference *pKid = (CPDF_Reference *)pKids; | |
| 4143 CPDF_PageNode *pNode = new CPDF_PageNode(); | |
| 4144 pPageNode->m_childNode.Add(pNode); | |
| 4145 pNode->m_dwPageNo = pKid->GetRefObjNum(); | |
| 4146 } | |
| 4147 break; | |
| 4148 case PDFOBJ_ARRAY: { | |
| 4149 CPDF_Array *pKidsArray = (CPDF_Array *)pKids; | |
| 4150 for (FX_DWORD i = 0; i < pKidsArray->GetCount(); ++i) { | |
| 4151 CPDF_Object *pKid = (CPDF_Object *)pKidsArray->GetElemen
t(i); | |
| 4152 if (!pKid || pKid->GetType() != PDFOBJ_REFERENCE) { | |
| 4153 continue; | |
| 4154 } | |
| 4155 CPDF_PageNode *pNode = new CPDF_PageNode(); | |
| 4156 pPageNode->m_childNode.Add(pNode); | |
| 4157 pNode->m_dwPageNo = ((CPDF_Reference*)pKid)->GetRefObjNu
m(); | |
| 4158 } | |
| 4159 } | |
| 4160 break; | |
| 4161 default: | |
| 4162 break; | |
| 4163 } | |
| 4164 } else if (type == FX_BSTRC("Page")) { | |
| 4165 pPageNode->m_type = PDF_PAGENODE_PAGE; | |
| 4166 } else { | |
| 4167 pPage->Release(); | |
| 4168 m_docStatus = PDF_DATAAVAIL_ERROR; | |
| 4169 return FALSE; | |
| 4170 } | |
| 4171 pPage->Release(); | |
| 4172 return TRUE; | 4323 return TRUE; |
| 4173 } | 4324 } |
| 4174 FX_BOOL CPDF_DataAvail::CheckPageNode(CPDF_PageNode &pageNodes, int32_t iPage, i
nt32_t &iCount, IFX_DownloadHints* pHints) | 4325 pPages->Release(); |
| 4175 { | 4326 return FALSE; |
| 4176 int32_t iSize = pageNodes.m_childNode.GetSize(); | 4327 } |
| 4177 if (iSize <= 0 || iPage >= iSize) { | 4328 FX_BOOL CPDF_DataAvail::LoadDocPages(IFX_DownloadHints* pHints) { |
| 4178 m_docStatus = PDF_DATAAVAIL_ERROR; | 4329 if (!CheckUnkownPageNode(m_PagesObjNum, &m_pageNodes, pHints)) { |
| 4179 return FALSE; | 4330 return FALSE; |
| 4180 } | 4331 } |
| 4181 for (int32_t i = 0; i < iSize; ++i) { | 4332 if (CheckPageCount(pHints)) { |
| 4182 CPDF_PageNode *pNode = (CPDF_PageNode*)pageNodes.m_childNode.GetAt(i); | 4333 m_docStatus = PDF_DATAAVAIL_PAGE; |
| 4183 if (!pNode) { | |
| 4184 continue; | |
| 4185 } | |
| 4186 switch (pNode->m_type) { | |
| 4187 case PDF_PAGENODE_UNKOWN: | |
| 4188 if (!CheckUnkownPageNode(pNode->m_dwPageNo, pNode, pHints)) { | |
| 4189 return FALSE; | |
| 4190 } | |
| 4191 --i; | |
| 4192 break; | |
| 4193 case PDF_PAGENODE_PAGE: | |
| 4194 iCount++; | |
| 4195 if (iPage == iCount && m_pDocument) { | |
| 4196 m_pDocument->m_PageList.SetAt(iPage, pNode->m_dwPageNo); | |
| 4197 } | |
| 4198 break; | |
| 4199 case PDF_PAGENODE_PAGES: | |
| 4200 if (!CheckPageNode(*pNode, iPage, iCount, pHints)) { | |
| 4201 return FALSE; | |
| 4202 } | |
| 4203 break; | |
| 4204 case PDF_PAGENODE_ARRAY: | |
| 4205 if (!CheckArrayPageNode(pNode->m_dwPageNo, pNode, pHints)) { | |
| 4206 return FALSE; | |
| 4207 } | |
| 4208 --i; | |
| 4209 break; | |
| 4210 } | |
| 4211 if (iPage == iCount) { | |
| 4212 m_docStatus = PDF_DATAAVAIL_DONE; | |
| 4213 return TRUE; | |
| 4214 } | |
| 4215 } | |
| 4216 return TRUE; | 4334 return TRUE; |
| 4217 } | 4335 } |
| 4218 FX_BOOL CPDF_DataAvail::LoadDocPage(int32_t iPage, IFX_DownloadHints* pHints) | 4336 m_bTotalLoadPageTree = TRUE; |
| 4219 { | 4337 return FALSE; |
| 4220 if (m_pDocument->GetPageCount() <= iPage || m_pDocument->m_PageList.GetAt(iP
age)) { | 4338 } |
| 4221 m_docStatus = PDF_DATAAVAIL_DONE; | 4339 FX_BOOL CPDF_DataAvail::LoadPages(IFX_DownloadHints* pHints) { |
| 4222 return TRUE; | 4340 while (!m_bPagesTreeLoad) { |
| 4223 } | 4341 if (!CheckPageStatus(pHints)) { |
| 4224 if (m_pageNodes.m_type == PDF_PAGENODE_PAGE) { | 4342 return FALSE; |
| 4225 if (iPage == 0) { | 4343 } |
| 4226 m_docStatus = PDF_DATAAVAIL_DONE; | 4344 } |
| 4227 return TRUE; | 4345 if (m_bPagesLoad) { |
| 4228 } | 4346 return TRUE; |
| 4229 m_docStatus = PDF_DATAAVAIL_ERROR; | 4347 } |
| 4230 return TRUE; | 4348 m_pDocument->LoadPages(); |
| 4231 } | 4349 return FALSE; |
| 4232 int32_t iCount = -1; | 4350 } |
| 4233 return CheckPageNode(m_pageNodes, iPage, iCount, pHints); | 4351 FX_BOOL CPDF_DataAvail::CheckLinearizedData(IFX_DownloadHints* pHints) { |
| 4234 } | 4352 if (m_bLinearedDataOK) { |
| 4235 FX_BOOL CPDF_DataAvail::CheckPageCount(IFX_DownloadHints* pHints) | 4353 return TRUE; |
| 4236 { | 4354 } |
| 4237 FX_BOOL bExist = FALSE; | 4355 |
| 4238 CPDF_Object *pPages = GetObject(m_PagesObjNum, pHints, &bExist); | 4356 if (!m_bMainXRefLoadTried) { |
| 4239 if (!bExist) { | 4357 FX_SAFE_DWORD data_size = m_dwFileLen; |
| 4240 m_docStatus = PDF_DATAAVAIL_ERROR; | 4358 data_size -= m_dwLastXRefOffset; |
| 4241 return FALSE; | 4359 if (!data_size.IsValid()) { |
| 4242 } | 4360 return FALSE; |
| 4243 if (!pPages) { | 4361 } |
| 4244 return FALSE; | 4362 if (!m_pFileAvail->IsDataAvail(m_dwLastXRefOffset, |
| 4245 } | 4363 data_size.ValueOrDie())) { |
| 4246 CPDF_Dictionary* pPagesDict = pPages->GetDict(); | 4364 pHints->AddSegment(m_dwLastXRefOffset, data_size.ValueOrDie()); |
| 4247 if (!pPagesDict) { | 4365 return FALSE; |
| 4248 pPages->Release(); | 4366 } |
| 4249 m_docStatus = PDF_DATAAVAIL_ERROR; | 4367 FX_DWORD dwRet = |
| 4250 return FALSE; | 4368 ((CPDF_Parser*)m_pDocument->GetParser())->LoadLinearizedMainXRefTable(); |
| 4251 } | 4369 m_bMainXRefLoadTried = TRUE; |
| 4252 if (!pPagesDict->KeyExist(FX_BSTRC("Kids"))) { | 4370 if (dwRet != PDFPARSE_ERROR_SUCCESS) { |
| 4253 pPages->Release(); | 4371 return FALSE; |
| 4254 return TRUE; | 4372 } |
| 4255 } | 4373 if (!PreparePageItem()) { |
| 4256 int count = pPagesDict->GetInteger(FX_BSTRC("Count")); | 4374 return FALSE; |
| 4257 if (count > 0) { | 4375 } |
| 4258 pPages->Release(); | 4376 m_bMainXRefLoadedOK = TRUE; |
| 4259 return TRUE; | 4377 m_bLinearedDataOK = TRUE; |
| 4260 } | 4378 } |
| 4261 pPages->Release(); | 4379 |
| 4262 return FALSE; | 4380 return m_bLinearedDataOK; |
| 4263 } | 4381 } |
| 4264 FX_BOOL CPDF_DataAvail::LoadDocPages(IFX_DownloadHints* pHints) | 4382 FX_BOOL CPDF_DataAvail::CheckPageAnnots(int32_t iPage, |
| 4265 { | 4383 IFX_DownloadHints* pHints) { |
| 4266 if (!CheckUnkownPageNode(m_PagesObjNum, &m_pageNodes, pHints)) { | 4384 if (!m_objs_array.GetSize()) { |
| 4267 return FALSE; | |
| 4268 } | |
| 4269 if (CheckPageCount(pHints)) { | |
| 4270 m_docStatus = PDF_DATAAVAIL_PAGE; | |
| 4271 return TRUE; | |
| 4272 } | |
| 4273 m_bTotalLoadPageTree = TRUE; | |
| 4274 return FALSE; | |
| 4275 } | |
| 4276 FX_BOOL CPDF_DataAvail::LoadPages(IFX_DownloadHints* pHints) | |
| 4277 { | |
| 4278 while (!m_bPagesTreeLoad) { | |
| 4279 if (!CheckPageStatus(pHints)) { | |
| 4280 return FALSE; | |
| 4281 } | |
| 4282 } | |
| 4283 if (m_bPagesLoad) { | |
| 4284 return TRUE; | |
| 4285 } | |
| 4286 m_pDocument->LoadPages(); | |
| 4287 return FALSE; | |
| 4288 } | |
| 4289 FX_BOOL CPDF_DataAvail::CheckLinearizedData(IFX_DownloadHints* pHints) | |
| 4290 { | |
| 4291 if (m_bLinearedDataOK) { | |
| 4292 return TRUE; | |
| 4293 } | |
| 4294 | |
| 4295 if (!m_bMainXRefLoadTried) { | |
| 4296 FX_SAFE_DWORD data_size = m_dwFileLen; | |
| 4297 data_size -= m_dwLastXRefOffset; | |
| 4298 if (!data_size.IsValid()) { | |
| 4299 return FALSE; | |
| 4300 } | |
| 4301 if (!m_pFileAvail->IsDataAvail(m_dwLastXRefOffset, data_size.ValueOrDie(
))) { | |
| 4302 pHints->AddSegment(m_dwLastXRefOffset, data_size.ValueOrDie()); | |
| 4303 return FALSE; | |
| 4304 } | |
| 4305 FX_DWORD dwRet = ((CPDF_Parser *)m_pDocument->GetParser())->LoadLineariz
edMainXRefTable(); | |
| 4306 m_bMainXRefLoadTried = TRUE; | |
| 4307 if (dwRet != PDFPARSE_ERROR_SUCCESS) { | |
| 4308 return FALSE; | |
| 4309 } | |
| 4310 if (!PreparePageItem()) { | |
| 4311 return FALSE; | |
| 4312 } | |
| 4313 m_bMainXRefLoadedOK = TRUE; | |
| 4314 m_bLinearedDataOK = TRUE; | |
| 4315 } | |
| 4316 | |
| 4317 return m_bLinearedDataOK; | |
| 4318 } | |
| 4319 FX_BOOL CPDF_DataAvail::CheckPageAnnots(int32_t iPage, IFX_DownloadHints* pHints
) | |
| 4320 { | |
| 4321 if (!m_objs_array.GetSize()) { | |
| 4322 m_objs_array.RemoveAll(); | |
| 4323 m_objnum_array.RemoveAll(); | |
| 4324 CPDF_Dictionary *pPageDict = m_pDocument->GetPage(iPage); | |
| 4325 if (!pPageDict) { | |
| 4326 return TRUE; | |
| 4327 } | |
| 4328 CPDF_Object *pAnnots = pPageDict->GetElement(FX_BSTRC("Annots")); | |
| 4329 if (!pAnnots) { | |
| 4330 return TRUE; | |
| 4331 } | |
| 4332 CFX_PtrArray obj_array; | |
| 4333 obj_array.Add(pAnnots); | |
| 4334 FX_BOOL bRet = IsObjectsAvail(obj_array, FALSE, pHints, m_objs_array); | |
| 4335 if (bRet) { | |
| 4336 m_objs_array.RemoveAll(); | |
| 4337 } | |
| 4338 return bRet; | |
| 4339 } | |
| 4340 CFX_PtrArray new_objs_array; | |
| 4341 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); | |
| 4342 m_objs_array.RemoveAll(); | 4385 m_objs_array.RemoveAll(); |
| 4343 if (!bRet) { | 4386 m_objnum_array.RemoveAll(); |
| 4344 m_objs_array.Append(new_objs_array); | 4387 CPDF_Dictionary* pPageDict = m_pDocument->GetPage(iPage); |
| 4388 if (!pPageDict) { |
| 4389 return TRUE; |
| 4390 } |
| 4391 CPDF_Object* pAnnots = pPageDict->GetElement(FX_BSTRC("Annots")); |
| 4392 if (!pAnnots) { |
| 4393 return TRUE; |
| 4394 } |
| 4395 CFX_PtrArray obj_array; |
| 4396 obj_array.Add(pAnnots); |
| 4397 FX_BOOL bRet = IsObjectsAvail(obj_array, FALSE, pHints, m_objs_array); |
| 4398 if (bRet) { |
| 4399 m_objs_array.RemoveAll(); |
| 4345 } | 4400 } |
| 4346 return bRet; | 4401 return bRet; |
| 4347 } | 4402 } |
| 4348 FX_BOOL CPDF_DataAvail::CheckLinearizedFirstPage(int32_t iPage, IFX_DownloadHint
s* pHints) | 4403 CFX_PtrArray new_objs_array; |
| 4349 { | 4404 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); |
| 4350 if (!m_bAnnotsLoad) { | 4405 m_objs_array.RemoveAll(); |
| 4351 if (!CheckPageAnnots(iPage, pHints)) { | 4406 if (!bRet) { |
| 4352 return FALSE; | 4407 m_objs_array.Append(new_objs_array); |
| 4353 } | 4408 } |
| 4354 m_bAnnotsLoad = TRUE; | 4409 return bRet; |
| 4355 } | 4410 } |
| 4356 if (m_bAnnotsLoad) { | 4411 FX_BOOL CPDF_DataAvail::CheckLinearizedFirstPage(int32_t iPage, |
| 4357 if (!CheckLinearizedData(pHints)) | 4412 IFX_DownloadHints* pHints) { |
| 4358 return FALSE; | 4413 if (!m_bAnnotsLoad) { |
| 4359 } | 4414 if (!CheckPageAnnots(iPage, pHints)) { |
| 4360 m_bPageLoadedOK = FALSE; | 4415 return FALSE; |
| 4416 } |
| 4417 m_bAnnotsLoad = TRUE; |
| 4418 } |
| 4419 if (m_bAnnotsLoad) { |
| 4420 if (!CheckLinearizedData(pHints)) |
| 4421 return FALSE; |
| 4422 } |
| 4423 m_bPageLoadedOK = FALSE; |
| 4424 return TRUE; |
| 4425 } |
| 4426 FX_BOOL CPDF_DataAvail::HaveResourceAncestor(CPDF_Dictionary* pDict) { |
| 4427 CFX_AutoRestorer<int> restorer(&s_CurrentDataAvailRecursionDepth); |
| 4428 if (++s_CurrentDataAvailRecursionDepth > kMaxDataAvailRecursionDepth) { |
| 4429 return FALSE; |
| 4430 } |
| 4431 CPDF_Object* pParent = pDict->GetElement("Parent"); |
| 4432 if (!pParent) { |
| 4433 return FALSE; |
| 4434 } |
| 4435 CPDF_Dictionary* pParentDict = pParent->GetDict(); |
| 4436 if (!pParentDict) { |
| 4437 return FALSE; |
| 4438 } |
| 4439 CPDF_Object* pRet = pParentDict->GetElement("Resources"); |
| 4440 if (pRet) { |
| 4441 m_pPageResource = pRet; |
| 4361 return TRUE; | 4442 return TRUE; |
| 4362 } | 4443 } |
| 4363 FX_BOOL CPDF_DataAvail::HaveResourceAncestor(CPDF_Dictionary *pDict) | 4444 return HaveResourceAncestor(pParentDict); |
| 4364 { | 4445 } |
| 4365 CFX_AutoRestorer<int> restorer(&s_CurrentDataAvailRecursionDepth); | 4446 FX_BOOL CPDF_DataAvail::IsPageAvail(int32_t iPage, IFX_DownloadHints* pHints) { |
| 4366 if (++s_CurrentDataAvailRecursionDepth > kMaxDataAvailRecursionDepth) { | 4447 if (!m_pDocument) { |
| 4367 return FALSE; | 4448 return FALSE; |
| 4368 } | 4449 } |
| 4369 CPDF_Object *pParent = pDict->GetElement("Parent"); | 4450 if (IsFirstCheck(iPage)) { |
| 4370 if (!pParent) { | 4451 m_bCurPageDictLoadOK = FALSE; |
| 4371 return FALSE; | |
| 4372 } | |
| 4373 CPDF_Dictionary *pParentDict = pParent->GetDict(); | |
| 4374 if (!pParentDict) { | |
| 4375 return FALSE; | |
| 4376 } | |
| 4377 CPDF_Object *pRet = pParentDict->GetElement("Resources"); | |
| 4378 if (pRet) { | |
| 4379 m_pPageResource = pRet; | |
| 4380 return TRUE; | |
| 4381 } | |
| 4382 return HaveResourceAncestor(pParentDict); | |
| 4383 } | |
| 4384 FX_BOOL CPDF_DataAvail::IsPageAvail(int32_t iPage, IFX_DownloadHints* pHints) | |
| 4385 { | |
| 4386 if (!m_pDocument) { | |
| 4387 return FALSE; | |
| 4388 } | |
| 4389 if (IsFirstCheck(iPage)) { | |
| 4390 m_bCurPageDictLoadOK = FALSE; | |
| 4391 m_bPageLoadedOK = FALSE; | |
| 4392 m_bAnnotsLoad = FALSE; | |
| 4393 m_bNeedDownLoadResource = FALSE; | |
| 4394 m_objs_array.RemoveAll(); | |
| 4395 m_objnum_array.RemoveAll(); | |
| 4396 } | |
| 4397 if (m_pagesLoadState == NULL) { | |
| 4398 m_pagesLoadState = new CFX_CMapDWordToDWord(); | |
| 4399 } | |
| 4400 FX_DWORD dwPageLoad = 0; | |
| 4401 if (m_pagesLoadState->Lookup(iPage, dwPageLoad) && dwPageLoad != 0) { | |
| 4402 return TRUE; | |
| 4403 } | |
| 4404 if (m_bLinearized) { | |
| 4405 if ((FX_DWORD)iPage == m_dwFirstPageNo) { | |
| 4406 m_pagesLoadState->SetAt(iPage, TRUE); | |
| 4407 return TRUE; | |
| 4408 } | |
| 4409 if (!CheckLinearizedData(pHints)) { | |
| 4410 return FALSE; | |
| 4411 } | |
| 4412 if (m_bMainXRefLoadedOK) { | |
| 4413 if (m_bTotalLoadPageTree) { | |
| 4414 if (!LoadPages(pHints)) { | |
| 4415 return FALSE; | |
| 4416 } | |
| 4417 } else { | |
| 4418 if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) { | |
| 4419 return FALSE; | |
| 4420 } | |
| 4421 } | |
| 4422 } else { | |
| 4423 if (!LoadAllFile(pHints)) { | |
| 4424 return FALSE; | |
| 4425 } | |
| 4426 ((CPDF_Parser *)m_pDocument->GetParser())->RebuildCrossRef(); | |
| 4427 ResetFirstCheck(iPage); | |
| 4428 return TRUE; | |
| 4429 } | |
| 4430 } else { | |
| 4431 if (!m_bTotalLoadPageTree) { | |
| 4432 if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) { | |
| 4433 return FALSE; | |
| 4434 } | |
| 4435 } | |
| 4436 } | |
| 4437 if (m_bHaveAcroForm && !m_bAcroFormLoad) { | |
| 4438 if (!CheckAcroFormSubObject(pHints)) { | |
| 4439 return FALSE; | |
| 4440 } | |
| 4441 m_bAcroFormLoad = TRUE; | |
| 4442 } | |
| 4443 if (!m_bPageLoadedOK) { | |
| 4444 if (!m_objs_array.GetSize()) { | |
| 4445 m_objs_array.RemoveAll(); | |
| 4446 m_objnum_array.RemoveAll(); | |
| 4447 m_pPageDict = m_pDocument->GetPage(iPage); | |
| 4448 if (!m_pPageDict) { | |
| 4449 ResetFirstCheck(iPage); | |
| 4450 return TRUE; | |
| 4451 } | |
| 4452 CFX_PtrArray obj_array; | |
| 4453 obj_array.Add(m_pPageDict); | |
| 4454 FX_BOOL bRet = IsObjectsAvail(obj_array, TRUE, pHints, m_objs_array)
; | |
| 4455 if (bRet) { | |
| 4456 m_objs_array.RemoveAll(); | |
| 4457 m_bPageLoadedOK = TRUE; | |
| 4458 } else { | |
| 4459 return bRet; | |
| 4460 } | |
| 4461 } else { | |
| 4462 CFX_PtrArray new_objs_array; | |
| 4463 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_
array); | |
| 4464 m_objs_array.RemoveAll(); | |
| 4465 if (bRet) { | |
| 4466 m_bPageLoadedOK = TRUE; | |
| 4467 } else { | |
| 4468 m_objs_array.Append(new_objs_array); | |
| 4469 return bRet; | |
| 4470 } | |
| 4471 } | |
| 4472 } | |
| 4473 if (m_bPageLoadedOK) { | |
| 4474 if (!m_bAnnotsLoad) { | |
| 4475 if (!CheckPageAnnots(iPage, pHints)) { | |
| 4476 return FALSE; | |
| 4477 } | |
| 4478 m_bAnnotsLoad = TRUE; | |
| 4479 } | |
| 4480 } | |
| 4481 if (m_pPageDict && !m_bNeedDownLoadResource) { | |
| 4482 m_pPageResource = m_pPageDict->GetElement("Resources"); | |
| 4483 if (!m_pPageResource) { | |
| 4484 m_bNeedDownLoadResource = HaveResourceAncestor(m_pPageDict); | |
| 4485 } else { | |
| 4486 m_bNeedDownLoadResource = TRUE; | |
| 4487 } | |
| 4488 } | |
| 4489 if (m_bNeedDownLoadResource) { | |
| 4490 FX_BOOL bRet = CheckResources(pHints); | |
| 4491 if (!bRet) { | |
| 4492 return FALSE; | |
| 4493 } | |
| 4494 m_bNeedDownLoadResource = FALSE; | |
| 4495 } | |
| 4496 m_bPageLoadedOK = FALSE; | 4452 m_bPageLoadedOK = FALSE; |
| 4497 m_bAnnotsLoad = FALSE; | 4453 m_bAnnotsLoad = FALSE; |
| 4498 m_bCurPageDictLoadOK = FALSE; | 4454 m_bNeedDownLoadResource = FALSE; |
| 4499 ResetFirstCheck(iPage); | 4455 m_objs_array.RemoveAll(); |
| 4500 m_pagesLoadState->SetAt(iPage, TRUE); | 4456 m_objnum_array.RemoveAll(); |
| 4457 } |
| 4458 if (m_pagesLoadState == NULL) { |
| 4459 m_pagesLoadState = new CFX_CMapDWordToDWord(); |
| 4460 } |
| 4461 FX_DWORD dwPageLoad = 0; |
| 4462 if (m_pagesLoadState->Lookup(iPage, dwPageLoad) && dwPageLoad != 0) { |
| 4501 return TRUE; | 4463 return TRUE; |
| 4502 } | 4464 } |
| 4503 FX_BOOL CPDF_DataAvail::CheckResources(IFX_DownloadHints* pHints) | 4465 if (m_bLinearized) { |
| 4504 { | 4466 if ((FX_DWORD)iPage == m_dwFirstPageNo) { |
| 4467 m_pagesLoadState->SetAt(iPage, TRUE); |
| 4468 return TRUE; |
| 4469 } |
| 4470 if (!CheckLinearizedData(pHints)) { |
| 4471 return FALSE; |
| 4472 } |
| 4473 if (m_bMainXRefLoadedOK) { |
| 4474 if (m_bTotalLoadPageTree) { |
| 4475 if (!LoadPages(pHints)) { |
| 4476 return FALSE; |
| 4477 } |
| 4478 } else { |
| 4479 if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) { |
| 4480 return FALSE; |
| 4481 } |
| 4482 } |
| 4483 } else { |
| 4484 if (!LoadAllFile(pHints)) { |
| 4485 return FALSE; |
| 4486 } |
| 4487 ((CPDF_Parser*)m_pDocument->GetParser())->RebuildCrossRef(); |
| 4488 ResetFirstCheck(iPage); |
| 4489 return TRUE; |
| 4490 } |
| 4491 } else { |
| 4492 if (!m_bTotalLoadPageTree) { |
| 4493 if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) { |
| 4494 return FALSE; |
| 4495 } |
| 4496 } |
| 4497 } |
| 4498 if (m_bHaveAcroForm && !m_bAcroFormLoad) { |
| 4499 if (!CheckAcroFormSubObject(pHints)) { |
| 4500 return FALSE; |
| 4501 } |
| 4502 m_bAcroFormLoad = TRUE; |
| 4503 } |
| 4504 if (!m_bPageLoadedOK) { |
| 4505 if (!m_objs_array.GetSize()) { | 4505 if (!m_objs_array.GetSize()) { |
| 4506 m_objs_array.RemoveAll(); |
| 4507 m_objnum_array.RemoveAll(); |
| 4508 m_pPageDict = m_pDocument->GetPage(iPage); |
| 4509 if (!m_pPageDict) { |
| 4510 ResetFirstCheck(iPage); |
| 4511 return TRUE; |
| 4512 } |
| 4513 CFX_PtrArray obj_array; |
| 4514 obj_array.Add(m_pPageDict); |
| 4515 FX_BOOL bRet = IsObjectsAvail(obj_array, TRUE, pHints, m_objs_array); |
| 4516 if (bRet) { |
| 4506 m_objs_array.RemoveAll(); | 4517 m_objs_array.RemoveAll(); |
| 4507 CFX_PtrArray obj_array; | 4518 m_bPageLoadedOK = TRUE; |
| 4508 obj_array.Add(m_pPageResource); | 4519 } else { |
| 4509 FX_BOOL bRet = IsObjectsAvail(obj_array, TRUE, pHints, m_objs_array); | |
| 4510 if (bRet) { | |
| 4511 m_objs_array.RemoveAll(); | |
| 4512 } | |
| 4513 return bRet; | 4520 return bRet; |
| 4514 } | 4521 } |
| 4515 CFX_PtrArray new_objs_array; | 4522 } else { |
| 4516 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); | 4523 CFX_PtrArray new_objs_array; |
| 4524 FX_BOOL bRet = |
| 4525 IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); |
| 4526 m_objs_array.RemoveAll(); |
| 4527 if (bRet) { |
| 4528 m_bPageLoadedOK = TRUE; |
| 4529 } else { |
| 4530 m_objs_array.Append(new_objs_array); |
| 4531 return bRet; |
| 4532 } |
| 4533 } |
| 4534 } |
| 4535 if (m_bPageLoadedOK) { |
| 4536 if (!m_bAnnotsLoad) { |
| 4537 if (!CheckPageAnnots(iPage, pHints)) { |
| 4538 return FALSE; |
| 4539 } |
| 4540 m_bAnnotsLoad = TRUE; |
| 4541 } |
| 4542 } |
| 4543 if (m_pPageDict && !m_bNeedDownLoadResource) { |
| 4544 m_pPageResource = m_pPageDict->GetElement("Resources"); |
| 4545 if (!m_pPageResource) { |
| 4546 m_bNeedDownLoadResource = HaveResourceAncestor(m_pPageDict); |
| 4547 } else { |
| 4548 m_bNeedDownLoadResource = TRUE; |
| 4549 } |
| 4550 } |
| 4551 if (m_bNeedDownLoadResource) { |
| 4552 FX_BOOL bRet = CheckResources(pHints); |
| 4553 if (!bRet) { |
| 4554 return FALSE; |
| 4555 } |
| 4556 m_bNeedDownLoadResource = FALSE; |
| 4557 } |
| 4558 m_bPageLoadedOK = FALSE; |
| 4559 m_bAnnotsLoad = FALSE; |
| 4560 m_bCurPageDictLoadOK = FALSE; |
| 4561 ResetFirstCheck(iPage); |
| 4562 m_pagesLoadState->SetAt(iPage, TRUE); |
| 4563 return TRUE; |
| 4564 } |
| 4565 FX_BOOL CPDF_DataAvail::CheckResources(IFX_DownloadHints* pHints) { |
| 4566 if (!m_objs_array.GetSize()) { |
| 4517 m_objs_array.RemoveAll(); | 4567 m_objs_array.RemoveAll(); |
| 4518 if (!bRet) { | 4568 CFX_PtrArray obj_array; |
| 4519 m_objs_array.Append(new_objs_array); | 4569 obj_array.Add(m_pPageResource); |
| 4570 FX_BOOL bRet = IsObjectsAvail(obj_array, TRUE, pHints, m_objs_array); |
| 4571 if (bRet) { |
| 4572 m_objs_array.RemoveAll(); |
| 4520 } | 4573 } |
| 4521 return bRet; | 4574 return bRet; |
| 4522 } | 4575 } |
| 4523 void CPDF_DataAvail::GetLinearizedMainXRefInfo(FX_FILESIZE *pPos, FX_DWORD *pSiz
e) | 4576 CFX_PtrArray new_objs_array; |
| 4524 { | 4577 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); |
| 4525 if (pPos) { | 4578 m_objs_array.RemoveAll(); |
| 4526 *pPos = m_dwLastXRefOffset; | 4579 if (!bRet) { |
| 4527 } | 4580 m_objs_array.Append(new_objs_array); |
| 4528 if (pSize) { | 4581 } |
| 4529 *pSize = (FX_DWORD)(m_dwFileLen - m_dwLastXRefOffset); | 4582 return bRet; |
| 4530 } | 4583 } |
| 4531 } | 4584 void CPDF_DataAvail::GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, |
| 4532 int32_t CPDF_DataAvail::IsFormAvail(IFX_DownloadHints *pHints) | 4585 FX_DWORD* pSize) { |
| 4533 { | 4586 if (pPos) { |
| 4534 if (!m_pDocument) { | 4587 *pPos = m_dwLastXRefOffset; |
| 4535 return PDFFORM_AVAIL; | 4588 } |
| 4536 } | 4589 if (pSize) { |
| 4537 if (!m_bLinearizedFormParamLoad) { | 4590 *pSize = (FX_DWORD)(m_dwFileLen - m_dwLastXRefOffset); |
| 4538 CPDF_Dictionary *pRoot = m_pDocument->GetRoot(); | 4591 } |
| 4539 if (!pRoot) { | 4592 } |
| 4540 return PDFFORM_AVAIL; | 4593 int32_t CPDF_DataAvail::IsFormAvail(IFX_DownloadHints* pHints) { |
| 4541 } | 4594 if (!m_pDocument) { |
| 4542 CPDF_Object *pAcroForm = pRoot->GetElement(FX_BSTRC("AcroForm")); | |
| 4543 if (!pAcroForm) { | |
| 4544 return PDFFORM_NOTEXIST; | |
| 4545 } | |
| 4546 if (!CheckLinearizedData(pHints)) { | |
| 4547 return PDFFORM_NOTAVAIL; | |
| 4548 } | |
| 4549 if (!m_objs_array.GetSize()) { | |
| 4550 m_objs_array.Add(pAcroForm->GetDict()); | |
| 4551 } | |
| 4552 m_bLinearizedFormParamLoad = TRUE; | |
| 4553 } | |
| 4554 CFX_PtrArray new_objs_array; | |
| 4555 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); | |
| 4556 m_objs_array.RemoveAll(); | |
| 4557 if (!bRet) { | |
| 4558 m_objs_array.Append(new_objs_array); | |
| 4559 return PDFFORM_NOTAVAIL; | |
| 4560 } | |
| 4561 return PDFFORM_AVAIL; | 4595 return PDFFORM_AVAIL; |
| 4562 } | 4596 } |
| 4563 void CPDF_SortObjNumArray::AddObjNum(FX_DWORD dwObjNum) | 4597 if (!m_bLinearizedFormParamLoad) { |
| 4564 { | 4598 CPDF_Dictionary* pRoot = m_pDocument->GetRoot(); |
| 4565 int32_t iNext = 0; | 4599 if (!pRoot) { |
| 4566 if (BinarySearch(dwObjNum, iNext)) { | 4600 return PDFFORM_AVAIL; |
| 4567 return; | 4601 } |
| 4568 } | 4602 CPDF_Object* pAcroForm = pRoot->GetElement(FX_BSTRC("AcroForm")); |
| 4569 m_number_array.InsertAt(iNext, dwObjNum); | 4603 if (!pAcroForm) { |
| 4570 } | 4604 return PDFFORM_NOTEXIST; |
| 4571 FX_BOOL CPDF_SortObjNumArray::Find(FX_DWORD dwObjNum) | 4605 } |
| 4572 { | 4606 if (!CheckLinearizedData(pHints)) { |
| 4573 int32_t iNext = 0; | 4607 return PDFFORM_NOTAVAIL; |
| 4574 return BinarySearch(dwObjNum, iNext); | 4608 } |
| 4575 } | 4609 if (!m_objs_array.GetSize()) { |
| 4576 FX_BOOL CPDF_SortObjNumArray::BinarySearch(FX_DWORD value, int32_t &iNext) | 4610 m_objs_array.Add(pAcroForm->GetDict()); |
| 4577 { | 4611 } |
| 4578 int32_t iLow = 0; | 4612 m_bLinearizedFormParamLoad = TRUE; |
| 4579 int32_t iHigh = m_number_array.GetSize() - 1; | 4613 } |
| 4580 while (iLow <= iHigh) { | 4614 CFX_PtrArray new_objs_array; |
| 4581 int32_t iMid = (iLow + iHigh) / 2; | 4615 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); |
| 4582 if (m_number_array.GetAt(iMid) == value) { | 4616 m_objs_array.RemoveAll(); |
| 4583 iNext = iMid; | 4617 if (!bRet) { |
| 4584 return TRUE; | 4618 m_objs_array.Append(new_objs_array); |
| 4585 } | 4619 return PDFFORM_NOTAVAIL; |
| 4586 if (m_number_array.GetAt(iMid) > value) { | 4620 } |
| 4587 iHigh = iMid - 1; | 4621 return PDFFORM_AVAIL; |
| 4588 } else if (m_number_array.GetAt(iMid) < value) { | 4622 } |
| 4589 iLow = iMid + 1; | 4623 void CPDF_SortObjNumArray::AddObjNum(FX_DWORD dwObjNum) { |
| 4590 } | 4624 int32_t iNext = 0; |
| 4591 } | 4625 if (BinarySearch(dwObjNum, iNext)) { |
| 4592 iNext = iLow; | 4626 return; |
| 4593 return FALSE; | 4627 } |
| 4594 } | 4628 m_number_array.InsertAt(iNext, dwObjNum); |
| 4595 CPDF_PageNode::~CPDF_PageNode() | 4629 } |
| 4596 { | 4630 FX_BOOL CPDF_SortObjNumArray::Find(FX_DWORD dwObjNum) { |
| 4597 int32_t iSize = m_childNode.GetSize(); | 4631 int32_t iNext = 0; |
| 4598 for (int32_t i = 0; i < iSize; ++i) { | 4632 return BinarySearch(dwObjNum, iNext); |
| 4599 CPDF_PageNode* pNode = (CPDF_PageNode*)m_childNode[i]; | 4633 } |
| 4600 delete pNode; | 4634 FX_BOOL CPDF_SortObjNumArray::BinarySearch(FX_DWORD value, int32_t& iNext) { |
| 4601 } | 4635 int32_t iLow = 0; |
| 4602 m_childNode.RemoveAll(); | 4636 int32_t iHigh = m_number_array.GetSize() - 1; |
| 4603 } | 4637 while (iLow <= iHigh) { |
| 4638 int32_t iMid = (iLow + iHigh) / 2; |
| 4639 if (m_number_array.GetAt(iMid) == value) { |
| 4640 iNext = iMid; |
| 4641 return TRUE; |
| 4642 } |
| 4643 if (m_number_array.GetAt(iMid) > value) { |
| 4644 iHigh = iMid - 1; |
| 4645 } else if (m_number_array.GetAt(iMid) < value) { |
| 4646 iLow = iMid + 1; |
| 4647 } |
| 4648 } |
| 4649 iNext = iLow; |
| 4650 return FALSE; |
| 4651 } |
| 4652 CPDF_PageNode::~CPDF_PageNode() { |
| 4653 int32_t iSize = m_childNode.GetSize(); |
| 4654 for (int32_t i = 0; i < iSize; ++i) { |
| 4655 CPDF_PageNode* pNode = (CPDF_PageNode*)m_childNode[i]; |
| 4656 delete pNode; |
| 4657 } |
| 4658 m_childNode.RemoveAll(); |
| 4659 } |
| OLD | NEW |