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 |