| 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 <set> | 7 #include <set> |
| 8 #include <utility> | 8 #include <utility> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "../../../../third_party/base/nonstd_unique_ptr.h" | 11 #include "../../../../third_party/base/nonstd_unique_ptr.h" |
| 12 #include "../../../include/fpdfapi/fpdf_module.h" | 12 #include "../../../include/fpdfapi/fpdf_module.h" |
| 13 #include "../../../include/fpdfapi/fpdf_page.h" | 13 #include "../../../include/fpdfapi/fpdf_page.h" |
| 14 #include "../../../include/fpdfapi/fpdf_parser.h" | 14 #include "../../../include/fpdfapi/fpdf_parser.h" |
| 15 #include "../../../include/fxcrt/fx_safe_types.h" | 15 #include "../../../include/fxcrt/fx_safe_types.h" |
| 16 #include "../fpdf_page/pageint.h" | 16 #include "../fpdf_page/pageint.h" |
| 17 | 17 |
| 18 namespace { | 18 namespace { |
| 19 | 19 |
| 20 struct SearchTagRecord { |
| 21 const uint8_t* m_pTag; |
| 22 FX_DWORD m_Len; |
| 23 FX_DWORD m_Offset; |
| 24 }; |
| 25 |
| 20 int CompareFileSize(const void* p1, const void* p2) { | 26 int CompareFileSize(const void* p1, const void* p2) { |
| 21 return *(FX_FILESIZE*)p1 - *(FX_FILESIZE*)p2; | 27 return *(FX_FILESIZE*)p1 - *(FX_FILESIZE*)p2; |
| 22 } | 28 } |
| 23 | 29 |
| 24 int32_t GetHeaderOffset(IFX_FileRead* pFile) { | 30 int32_t GetHeaderOffset(IFX_FileRead* pFile) { |
| 25 const FX_DWORD tag = FXDWORD_FROM_LSBFIRST(0x46445025); | 31 const FX_DWORD tag = FXDWORD_FROM_LSBFIRST(0x46445025); |
| 26 const size_t kBufSize = 4; | 32 const size_t kBufSize = 4; |
| 27 uint8_t buf[kBufSize]; | 33 uint8_t buf[kBufSize]; |
| 28 int32_t offset = 0; | 34 int32_t offset = 0; |
| 29 while (offset <= 1024) { | 35 while (offset <= 1024) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 52 return !pObj || pObj->GetType() == iType; | 58 return !pObj || pObj->GetType() == iType; |
| 53 } | 59 } |
| 54 | 60 |
| 55 FX_DWORD GetVarInt(const uint8_t* p, int32_t n) { | 61 FX_DWORD GetVarInt(const uint8_t* p, int32_t n) { |
| 56 FX_DWORD result = 0; | 62 FX_DWORD result = 0; |
| 57 for (int32_t i = 0; i < n; ++i) | 63 for (int32_t i = 0; i < n; ++i) |
| 58 result = result * 256 + p[i]; | 64 result = result * 256 + p[i]; |
| 59 return result; | 65 return result; |
| 60 } | 66 } |
| 61 | 67 |
| 68 int32_t GetStreamNCount(CPDF_StreamAcc* pObjStream) { |
| 69 return pObjStream->GetDict()->GetInteger(FX_BSTRC("N")); |
| 70 } |
| 71 |
| 72 int32_t GetStreamFirst(CPDF_StreamAcc* pObjStream) { |
| 73 return pObjStream->GetDict()->GetInteger(FX_BSTRC("First")); |
| 74 } |
| 75 |
| 62 } // namespace | 76 } // namespace |
| 63 | 77 |
| 78 // TODO(thestig) Using unique_ptr with ReleaseDeleter is still not ideal. |
| 79 // Come up or wait for something better. |
| 80 using ScopedFileStream = |
| 81 nonstd::unique_ptr<IFX_FileStream, ReleaseDeleter<IFX_FileStream>>; |
| 82 |
| 64 FX_BOOL IsSignatureDict(const CPDF_Dictionary* pDict) { | 83 FX_BOOL IsSignatureDict(const CPDF_Dictionary* pDict) { |
| 65 CPDF_Object* pType = pDict->GetElementValue(FX_BSTRC("Type")); | 84 CPDF_Object* pType = pDict->GetElementValue(FX_BSTRC("Type")); |
| 66 if (!pType) { | 85 if (!pType) { |
| 67 pType = pDict->GetElementValue(FX_BSTRC("FT")); | 86 pType = pDict->GetElementValue(FX_BSTRC("FT")); |
| 68 if (!pType) { | 87 if (!pType) { |
| 69 return FALSE; | 88 return FALSE; |
| 70 } | 89 } |
| 71 } | 90 } |
| 72 if (pType->GetString() == FX_BSTRC("Sig")) { | 91 if (pType->GetString() == FX_BSTRC("Sig")) { |
| 73 return TRUE; | 92 return TRUE; |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 return FALSE; | 373 return FALSE; |
| 355 } | 374 } |
| 356 FX_FILESIZE newxrefpos = GetDirectInteger(m_pTrailer, FX_BSTRC("Prev")); | 375 FX_FILESIZE newxrefpos = GetDirectInteger(m_pTrailer, FX_BSTRC("Prev")); |
| 357 if (newxrefpos == xrefpos) { | 376 if (newxrefpos == xrefpos) { |
| 358 return FALSE; | 377 return FALSE; |
| 359 } | 378 } |
| 360 xrefpos = newxrefpos; | 379 xrefpos = newxrefpos; |
| 361 while (xrefpos) { | 380 while (xrefpos) { |
| 362 CrossRefList.InsertAt(0, xrefpos); | 381 CrossRefList.InsertAt(0, xrefpos); |
| 363 LoadCrossRefV4(xrefpos, 0, TRUE, FALSE); | 382 LoadCrossRefV4(xrefpos, 0, TRUE, FALSE); |
| 364 CPDF_Dictionary* pDict = LoadTrailerV4(); | 383 nonstd::unique_ptr<CPDF_Dictionary, ReleaseDeleter<CPDF_Dictionary>> pDict( |
| 365 if (pDict == NULL) { | 384 LoadTrailerV4()); |
| 385 if (!pDict) |
| 366 return FALSE; | 386 return FALSE; |
| 367 } | 387 |
| 368 if (!CheckDirectType(pDict, FX_BSTRC("Prev"), PDFOBJ_NUMBER)) { | 388 if (!CheckDirectType(pDict.get(), FX_BSTRC("Prev"), PDFOBJ_NUMBER)) |
| 369 pDict->Release(); | |
| 370 return FALSE; | 389 return FALSE; |
| 371 } | 390 |
| 372 newxrefpos = GetDirectInteger(pDict, FX_BSTRC("Prev")); | 391 newxrefpos = GetDirectInteger(pDict.get(), FX_BSTRC("Prev")); |
| 373 if (newxrefpos == xrefpos) { | 392 if (newxrefpos == xrefpos) |
| 374 pDict->Release(); | |
| 375 return FALSE; | 393 return FALSE; |
| 376 } | 394 |
| 377 xrefpos = newxrefpos; | 395 xrefpos = newxrefpos; |
| 378 XRefStreamList.InsertAt(0, pDict->GetInteger(FX_BSTRC("XRefStm"))); | 396 XRefStreamList.InsertAt(0, pDict->GetInteger(FX_BSTRC("XRefStm"))); |
| 379 m_Trailers.Add(pDict); | 397 m_Trailers.Add(pDict.release()); |
| 380 } | 398 } |
| 381 for (int32_t i = 0; i < CrossRefList.GetSize(); i++) | 399 for (int32_t i = 0; i < CrossRefList.GetSize(); i++) { |
| 382 if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE, i == 0)) { | 400 if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE, i == 0)) |
| 383 return FALSE; | 401 return FALSE; |
| 384 } | 402 } |
| 385 return TRUE; | 403 return TRUE; |
| 386 } | 404 } |
| 387 FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV4(FX_FILESIZE xrefpos, | 405 FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV4(FX_FILESIZE xrefpos, |
| 388 FX_DWORD dwObjCount) { | 406 FX_DWORD dwObjCount) { |
| 389 if (!LoadLinearizedCrossRefV4(xrefpos, dwObjCount)) { | 407 if (!LoadLinearizedCrossRefV4(xrefpos, dwObjCount)) { |
| 390 return FALSE; | 408 return FALSE; |
| 391 } | 409 } |
| 392 m_pTrailer = LoadTrailerV4(); | 410 m_pTrailer = LoadTrailerV4(); |
| 393 if (m_pTrailer == NULL) { | 411 if (m_pTrailer == NULL) { |
| 394 return FALSE; | 412 return FALSE; |
| (...skipping 795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1190 m_SortedOffset.GetSize() - 1) { | 1208 m_SortedOffset.GetSize() - 1) { |
| 1191 return FALSE; | 1209 return FALSE; |
| 1192 } | 1210 } |
| 1193 FX_FILESIZE size = ((FX_FILESIZE*)pResult)[1] - pos; | 1211 FX_FILESIZE size = ((FX_FILESIZE*)pResult)[1] - pos; |
| 1194 FX_FILESIZE SavedPos = m_Syntax.SavePos(); | 1212 FX_FILESIZE SavedPos = m_Syntax.SavePos(); |
| 1195 m_Syntax.RestorePos(pos); | 1213 m_Syntax.RestorePos(pos); |
| 1196 bForm = m_Syntax.SearchMultiWord(FX_BSTRC("/Form\0stream"), TRUE, size) == 0; | 1214 bForm = m_Syntax.SearchMultiWord(FX_BSTRC("/Form\0stream"), TRUE, size) == 0; |
| 1197 m_Syntax.RestorePos(SavedPos); | 1215 m_Syntax.RestorePos(SavedPos); |
| 1198 return TRUE; | 1216 return TRUE; |
| 1199 } | 1217 } |
| 1218 |
| 1200 CPDF_Object* CPDF_Parser::ParseIndirectObject(CPDF_IndirectObjects* pObjList, | 1219 CPDF_Object* CPDF_Parser::ParseIndirectObject(CPDF_IndirectObjects* pObjList, |
| 1201 FX_DWORD objnum, | 1220 FX_DWORD objnum, |
| 1202 PARSE_CONTEXT* pContext) { | 1221 PARSE_CONTEXT* pContext) { |
| 1203 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) { | 1222 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) |
| 1204 return NULL; | 1223 return nullptr; |
| 1205 } | 1224 |
| 1206 if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) { | 1225 if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) { |
| 1207 FX_FILESIZE pos = m_CrossRef[objnum]; | 1226 FX_FILESIZE pos = m_CrossRef[objnum]; |
| 1208 if (pos <= 0) { | 1227 if (pos <= 0) |
| 1209 return NULL; | 1228 return nullptr; |
| 1210 } | |
| 1211 return ParseIndirectObjectAt(pObjList, pos, objnum, pContext); | 1229 return ParseIndirectObjectAt(pObjList, pos, objnum, pContext); |
| 1212 } | 1230 } |
| 1213 if (m_V5Type[objnum] == 2) { | 1231 if (m_V5Type[objnum] != 2) |
| 1214 CPDF_StreamAcc* pObjStream = GetObjectStream((FX_DWORD)m_CrossRef[objnum]); | 1232 return nullptr; |
| 1215 if (pObjStream == NULL) { | 1233 |
| 1216 return NULL; | 1234 CPDF_StreamAcc* pObjStream = GetObjectStream((FX_DWORD)m_CrossRef[objnum]); |
| 1235 if (!pObjStream) |
| 1236 return nullptr; |
| 1237 |
| 1238 ScopedFileStream file(FX_CreateMemoryStream( |
| 1239 (uint8_t*)pObjStream->GetData(), (size_t)pObjStream->GetSize(), FALSE)); |
| 1240 CPDF_SyntaxParser syntax; |
| 1241 syntax.InitParser(file.get(), 0); |
| 1242 int32_t offset = GetStreamFirst(pObjStream); |
| 1243 for (int32_t i = GetStreamNCount(pObjStream); i > 0; --i) { |
| 1244 FX_DWORD thisnum = syntax.GetDirectNum(); |
| 1245 FX_DWORD thisoff = syntax.GetDirectNum(); |
| 1246 if (thisnum == objnum) { |
| 1247 syntax.RestorePos(offset + thisoff); |
| 1248 return syntax.GetObject(pObjList, 0, 0, pContext); |
| 1217 } | 1249 } |
| 1218 int32_t n = pObjStream->GetDict()->GetInteger(FX_BSTRC("N")); | |
| 1219 int32_t offset = pObjStream->GetDict()->GetInteger(FX_BSTRC("First")); | |
| 1220 CPDF_SyntaxParser syntax; | |
| 1221 CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream( | |
| 1222 (uint8_t*)pObjStream->GetData(), (size_t)pObjStream->GetSize(), FALSE)); | |
| 1223 syntax.InitParser(file.Get(), 0); | |
| 1224 CPDF_Object* pRet = NULL; | |
| 1225 while (n) { | |
| 1226 FX_DWORD thisnum = syntax.GetDirectNum(); | |
| 1227 FX_DWORD thisoff = syntax.GetDirectNum(); | |
| 1228 if (thisnum == objnum) { | |
| 1229 syntax.RestorePos(offset + thisoff); | |
| 1230 pRet = syntax.GetObject(pObjList, 0, 0, pContext); | |
| 1231 break; | |
| 1232 } | |
| 1233 n--; | |
| 1234 } | |
| 1235 return pRet; | |
| 1236 } | 1250 } |
| 1237 return NULL; | 1251 return nullptr; |
| 1238 } | 1252 } |
| 1253 |
| 1239 CPDF_StreamAcc* CPDF_Parser::GetObjectStream(FX_DWORD objnum) { | 1254 CPDF_StreamAcc* CPDF_Parser::GetObjectStream(FX_DWORD objnum) { |
| 1240 CPDF_StreamAcc* pStreamAcc = NULL; | 1255 CPDF_StreamAcc* pStreamAcc = NULL; |
| 1241 if (m_ObjectStreamMap.Lookup((void*)(uintptr_t)objnum, (void*&)pStreamAcc)) { | 1256 if (m_ObjectStreamMap.Lookup((void*)(uintptr_t)objnum, (void*&)pStreamAcc)) { |
| 1242 return pStreamAcc; | 1257 return pStreamAcc; |
| 1243 } | 1258 } |
| 1244 const CPDF_Stream* pStream = | 1259 const CPDF_Stream* pStream = |
| 1245 m_pDocument ? (CPDF_Stream*)m_pDocument->GetIndirectObject(objnum) : NULL; | 1260 m_pDocument ? (CPDF_Stream*)m_pDocument->GetIndirectObject(objnum) : NULL; |
| 1246 if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM) { | 1261 if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM) { |
| 1247 return NULL; | 1262 return NULL; |
| 1248 } | 1263 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1280 void CPDF_Parser::GetIndirectBinary(FX_DWORD objnum, | 1295 void CPDF_Parser::GetIndirectBinary(FX_DWORD objnum, |
| 1281 uint8_t*& pBuffer, | 1296 uint8_t*& pBuffer, |
| 1282 FX_DWORD& size) { | 1297 FX_DWORD& size) { |
| 1283 pBuffer = NULL; | 1298 pBuffer = NULL; |
| 1284 size = 0; | 1299 size = 0; |
| 1285 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) { | 1300 if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) { |
| 1286 return; | 1301 return; |
| 1287 } | 1302 } |
| 1288 if (m_V5Type[objnum] == 2) { | 1303 if (m_V5Type[objnum] == 2) { |
| 1289 CPDF_StreamAcc* pObjStream = GetObjectStream((FX_DWORD)m_CrossRef[objnum]); | 1304 CPDF_StreamAcc* pObjStream = GetObjectStream((FX_DWORD)m_CrossRef[objnum]); |
| 1290 if (pObjStream == NULL) { | 1305 if (!pObjStream) |
| 1291 return; | 1306 return; |
| 1292 } | 1307 |
| 1293 int32_t n = pObjStream->GetDict()->GetInteger(FX_BSTRC("N")); | 1308 int32_t offset = GetStreamFirst(pObjStream); |
| 1294 int32_t offset = pObjStream->GetDict()->GetInteger(FX_BSTRC("First")); | |
| 1295 CPDF_SyntaxParser syntax; | |
| 1296 const uint8_t* pData = pObjStream->GetData(); | 1309 const uint8_t* pData = pObjStream->GetData(); |
| 1297 FX_DWORD totalsize = pObjStream->GetSize(); | 1310 FX_DWORD totalsize = pObjStream->GetSize(); |
| 1298 CFX_SmartPointer<IFX_FileStream> file( | 1311 ScopedFileStream file( |
| 1299 FX_CreateMemoryStream((uint8_t*)pData, (size_t)totalsize, FALSE)); | 1312 FX_CreateMemoryStream((uint8_t*)pData, (size_t)totalsize, FALSE)); |
| 1300 syntax.InitParser(file.Get(), 0); | 1313 CPDF_SyntaxParser syntax; |
| 1301 while (n) { | 1314 syntax.InitParser(file.get(), 0); |
| 1315 for (int i = GetStreamNCount(pObjStream); i > 0; --i) { |
| 1302 FX_DWORD thisnum = syntax.GetDirectNum(); | 1316 FX_DWORD thisnum = syntax.GetDirectNum(); |
| 1303 FX_DWORD thisoff = syntax.GetDirectNum(); | 1317 FX_DWORD thisoff = syntax.GetDirectNum(); |
| 1304 if (thisnum == objnum) { | 1318 if (thisnum != objnum) |
| 1305 if (n == 1) { | 1319 continue; |
| 1306 size = totalsize - (thisoff + offset); | 1320 |
| 1307 } else { | 1321 if (i == 1) { |
| 1308 syntax.GetDirectNum(); // Skip nextnum. | 1322 size = totalsize - (thisoff + offset); |
| 1309 FX_DWORD nextoff = syntax.GetDirectNum(); | 1323 } else { |
| 1310 size = nextoff - thisoff; | 1324 syntax.GetDirectNum(); // Skip nextnum. |
| 1311 } | 1325 FX_DWORD nextoff = syntax.GetDirectNum(); |
| 1312 pBuffer = FX_Alloc(uint8_t, size); | 1326 size = nextoff - thisoff; |
| 1313 FXSYS_memcpy(pBuffer, pData + thisoff + offset, size); | |
| 1314 return; | |
| 1315 } | 1327 } |
| 1316 n--; | 1328 pBuffer = FX_Alloc(uint8_t, size); |
| 1329 FXSYS_memcpy(pBuffer, pData + thisoff + offset, size); |
| 1330 return; |
| 1317 } | 1331 } |
| 1318 return; | 1332 return; |
| 1319 } | 1333 } |
| 1320 if (m_V5Type[objnum] == 1) { | 1334 |
| 1321 FX_FILESIZE pos = m_CrossRef[objnum]; | 1335 if (m_V5Type[objnum] != 1) |
| 1322 if (pos == 0) { | 1336 return; |
| 1323 return; | 1337 |
| 1324 } | 1338 FX_FILESIZE pos = m_CrossRef[objnum]; |
| 1325 FX_FILESIZE SavedPos = m_Syntax.SavePos(); | 1339 if (pos == 0) { |
| 1326 m_Syntax.RestorePos(pos); | 1340 return; |
| 1327 FX_BOOL bIsNumber; | 1341 } |
| 1328 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); | 1342 FX_FILESIZE SavedPos = m_Syntax.SavePos(); |
| 1329 if (!bIsNumber) { | 1343 m_Syntax.RestorePos(pos); |
| 1330 m_Syntax.RestorePos(SavedPos); | 1344 FX_BOOL bIsNumber; |
| 1331 return; | 1345 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); |
| 1332 } | 1346 if (!bIsNumber) { |
| 1333 FX_DWORD parser_objnum = FXSYS_atoi(word); | 1347 m_Syntax.RestorePos(SavedPos); |
| 1334 if (parser_objnum && parser_objnum != objnum) { | 1348 return; |
| 1335 m_Syntax.RestorePos(SavedPos); | 1349 } |
| 1336 return; | 1350 FX_DWORD parser_objnum = FXSYS_atoi(word); |
| 1337 } | 1351 if (parser_objnum && parser_objnum != objnum) { |
| 1352 m_Syntax.RestorePos(SavedPos); |
| 1353 return; |
| 1354 } |
| 1355 word = m_Syntax.GetNextWord(bIsNumber); |
| 1356 if (!bIsNumber) { |
| 1357 m_Syntax.RestorePos(SavedPos); |
| 1358 return; |
| 1359 } |
| 1360 if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) { |
| 1361 m_Syntax.RestorePos(SavedPos); |
| 1362 return; |
| 1363 } |
| 1364 void* pResult = |
| 1365 FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), |
| 1366 sizeof(FX_FILESIZE), CompareFileSize); |
| 1367 if (pResult == NULL) { |
| 1368 m_Syntax.RestorePos(SavedPos); |
| 1369 return; |
| 1370 } |
| 1371 FX_FILESIZE nextoff = ((FX_FILESIZE*)pResult)[1]; |
| 1372 FX_BOOL bNextOffValid = FALSE; |
| 1373 if (nextoff != pos) { |
| 1374 m_Syntax.RestorePos(nextoff); |
| 1338 word = m_Syntax.GetNextWord(bIsNumber); | 1375 word = m_Syntax.GetNextWord(bIsNumber); |
| 1339 if (!bIsNumber) { | 1376 if (word == FX_BSTRC("xref")) { |
| 1340 m_Syntax.RestorePos(SavedPos); | 1377 bNextOffValid = TRUE; |
| 1341 return; | 1378 } else if (bIsNumber) { |
| 1342 } | |
| 1343 if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) { | |
| 1344 m_Syntax.RestorePos(SavedPos); | |
| 1345 return; | |
| 1346 } | |
| 1347 void* pResult = | |
| 1348 FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), | |
| 1349 sizeof(FX_FILESIZE), CompareFileSize); | |
| 1350 if (pResult == NULL) { | |
| 1351 m_Syntax.RestorePos(SavedPos); | |
| 1352 return; | |
| 1353 } | |
| 1354 FX_FILESIZE nextoff = ((FX_FILESIZE*)pResult)[1]; | |
| 1355 FX_BOOL bNextOffValid = FALSE; | |
| 1356 if (nextoff != pos) { | |
| 1357 m_Syntax.RestorePos(nextoff); | |
| 1358 word = m_Syntax.GetNextWord(bIsNumber); | 1379 word = m_Syntax.GetNextWord(bIsNumber); |
| 1359 if (word == FX_BSTRC("xref")) { | 1380 if (bIsNumber && m_Syntax.GetKeyword() == FX_BSTRC("obj")) { |
| 1360 bNextOffValid = TRUE; | 1381 bNextOffValid = TRUE; |
| 1361 } else if (bIsNumber) { | |
| 1362 word = m_Syntax.GetNextWord(bIsNumber); | |
| 1363 if (bIsNumber && m_Syntax.GetKeyword() == FX_BSTRC("obj")) { | |
| 1364 bNextOffValid = TRUE; | |
| 1365 } | |
| 1366 } | 1382 } |
| 1367 } | 1383 } |
| 1368 if (!bNextOffValid) { | 1384 } |
| 1369 m_Syntax.RestorePos(pos); | 1385 if (!bNextOffValid) { |
| 1370 while (1) { | 1386 m_Syntax.RestorePos(pos); |
| 1371 if (m_Syntax.GetKeyword() == FX_BSTRC("endobj")) { | 1387 while (1) { |
| 1372 break; | 1388 if (m_Syntax.GetKeyword() == FX_BSTRC("endobj")) { |
| 1373 } | 1389 break; |
| 1374 if (m_Syntax.SavePos() == m_Syntax.m_FileLen) { | |
| 1375 break; | |
| 1376 } | |
| 1377 } | 1390 } |
| 1378 nextoff = m_Syntax.SavePos(); | 1391 if (m_Syntax.SavePos() == m_Syntax.m_FileLen) { |
| 1392 break; |
| 1393 } |
| 1379 } | 1394 } |
| 1380 size = (FX_DWORD)(nextoff - pos); | 1395 nextoff = m_Syntax.SavePos(); |
| 1381 pBuffer = FX_Alloc(uint8_t, size); | |
| 1382 m_Syntax.RestorePos(pos); | |
| 1383 m_Syntax.ReadBlock(pBuffer, size); | |
| 1384 m_Syntax.RestorePos(SavedPos); | |
| 1385 } | 1396 } |
| 1397 size = (FX_DWORD)(nextoff - pos); |
| 1398 pBuffer = FX_Alloc(uint8_t, size); |
| 1399 m_Syntax.RestorePos(pos); |
| 1400 m_Syntax.ReadBlock(pBuffer, size); |
| 1401 m_Syntax.RestorePos(SavedPos); |
| 1386 } | 1402 } |
| 1403 |
| 1387 CPDF_Object* CPDF_Parser::ParseIndirectObjectAt(CPDF_IndirectObjects* pObjList, | 1404 CPDF_Object* CPDF_Parser::ParseIndirectObjectAt(CPDF_IndirectObjects* pObjList, |
| 1388 FX_FILESIZE pos, | 1405 FX_FILESIZE pos, |
| 1389 FX_DWORD objnum, | 1406 FX_DWORD objnum, |
| 1390 PARSE_CONTEXT* pContext) { | 1407 PARSE_CONTEXT* pContext) { |
| 1391 FX_FILESIZE SavedPos = m_Syntax.SavePos(); | 1408 FX_FILESIZE SavedPos = m_Syntax.SavePos(); |
| 1392 m_Syntax.RestorePos(pos); | 1409 m_Syntax.RestorePos(pos); |
| 1393 FX_BOOL bIsNumber; | 1410 FX_BOOL bIsNumber; |
| 1394 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); | 1411 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); |
| 1395 if (!bIsNumber) { | 1412 if (!bIsNumber) { |
| 1396 m_Syntax.RestorePos(SavedPos); | 1413 m_Syntax.RestorePos(SavedPos); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1459 return NULL; | 1476 return NULL; |
| 1460 } | 1477 } |
| 1461 CPDF_Object* pObj = | 1478 CPDF_Object* pObj = |
| 1462 m_Syntax.GetObjectByStrict(pObjList, objnum, gennum, pContext); | 1479 m_Syntax.GetObjectByStrict(pObjList, objnum, gennum, pContext); |
| 1463 if (pResultPos) { | 1480 if (pResultPos) { |
| 1464 *pResultPos = m_Syntax.m_Pos; | 1481 *pResultPos = m_Syntax.m_Pos; |
| 1465 } | 1482 } |
| 1466 m_Syntax.RestorePos(SavedPos); | 1483 m_Syntax.RestorePos(SavedPos); |
| 1467 return pObj; | 1484 return pObj; |
| 1468 } | 1485 } |
| 1486 |
| 1469 CPDF_Dictionary* CPDF_Parser::LoadTrailerV4() { | 1487 CPDF_Dictionary* CPDF_Parser::LoadTrailerV4() { |
| 1470 if (m_Syntax.GetKeyword() != FX_BSTRC("trailer")) { | 1488 if (m_Syntax.GetKeyword() != FX_BSTRC("trailer")) |
| 1471 return NULL; | 1489 return nullptr; |
| 1472 } | 1490 |
| 1473 CPDF_Object* pObj = m_Syntax.GetObject(m_pDocument, 0, 0, 0); | 1491 nonstd::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>> pObj( |
| 1474 if (pObj == NULL || pObj->GetType() != PDFOBJ_DICTIONARY) { | 1492 m_Syntax.GetObject(m_pDocument, 0, 0, 0)); |
| 1475 if (pObj) { | 1493 if (!pObj || pObj->GetType() != PDFOBJ_DICTIONARY) |
| 1476 pObj->Release(); | 1494 return nullptr; |
| 1477 } | 1495 return static_cast<CPDF_Dictionary*>(pObj.release()); |
| 1478 return NULL; | |
| 1479 } | |
| 1480 return (CPDF_Dictionary*)pObj; | |
| 1481 } | 1496 } |
| 1497 |
| 1482 FX_DWORD CPDF_Parser::GetPermissions(FX_BOOL bCheckRevision) { | 1498 FX_DWORD CPDF_Parser::GetPermissions(FX_BOOL bCheckRevision) { |
| 1483 if (m_pSecurityHandler == NULL) { | 1499 if (m_pSecurityHandler == NULL) { |
| 1484 return (FX_DWORD)-1; | 1500 return (FX_DWORD)-1; |
| 1485 } | 1501 } |
| 1486 FX_DWORD dwPermission = m_pSecurityHandler->GetPermissions(); | 1502 FX_DWORD dwPermission = m_pSecurityHandler->GetPermissions(); |
| 1487 if (m_pEncryptDict && | 1503 if (m_pEncryptDict && |
| 1488 m_pEncryptDict->GetString(FX_BSTRC("Filter")) == FX_BSTRC("Standard")) { | 1504 m_pEncryptDict->GetString(FX_BSTRC("Filter")) == FX_BSTRC("Standard")) { |
| 1489 dwPermission &= 0xFFFFFFFC; | 1505 dwPermission &= 0xFFFFFFFC; |
| 1490 dwPermission |= 0xFFFFF0C0; | 1506 dwPermission |= 0xFFFFF0C0; |
| 1491 if (bCheckRevision && m_pEncryptDict->GetInteger(FX_BSTRC("R")) == 2) { | 1507 if (bCheckRevision && m_pEncryptDict->GetInteger(FX_BSTRC("R")) == 2) { |
| (...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2126 if (m_pCryptoHandler && bDecrypt) { | 2142 if (m_pCryptoHandler && bDecrypt) { |
| 2127 m_pCryptoHandler->Decrypt(objnum, gennum, str); | 2143 m_pCryptoHandler->Decrypt(objnum, gennum, str); |
| 2128 } | 2144 } |
| 2129 return CPDF_String::Create(str, TRUE); | 2145 return CPDF_String::Create(str, TRUE); |
| 2130 } | 2146 } |
| 2131 if (word == FX_BSTRC("[")) { | 2147 if (word == FX_BSTRC("[")) { |
| 2132 if (bTypeOnly) { | 2148 if (bTypeOnly) { |
| 2133 return (CPDF_Object*)PDFOBJ_ARRAY; | 2149 return (CPDF_Object*)PDFOBJ_ARRAY; |
| 2134 } | 2150 } |
| 2135 CPDF_Array* pArray = CPDF_Array::Create(); | 2151 CPDF_Array* pArray = CPDF_Array::Create(); |
| 2136 while (1) { | 2152 while (CPDF_Object* pObj = GetObject(pObjList, objnum, gennum)) |
| 2137 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum); | |
| 2138 if (pObj == NULL) { | |
| 2139 return pArray; | |
| 2140 } | |
| 2141 pArray->Add(pObj); | 2153 pArray->Add(pObj); |
| 2142 } | 2154 |
| 2155 return pArray; |
| 2143 } | 2156 } |
| 2144 if (word[0] == '/') { | 2157 if (word[0] == '/') { |
| 2145 if (bTypeOnly) { | 2158 if (bTypeOnly) { |
| 2146 return (CPDF_Object*)PDFOBJ_NAME; | 2159 return (CPDF_Object*)PDFOBJ_NAME; |
| 2147 } | 2160 } |
| 2148 return CPDF_Name::Create( | 2161 return CPDF_Name::Create( |
| 2149 PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))); | 2162 PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))); |
| 2150 } | 2163 } |
| 2151 if (word == FX_BSTRC("<<")) { | 2164 if (word == FX_BSTRC("<<")) { |
| 2152 if (bTypeOnly) { | 2165 if (bTypeOnly) |
| 2153 return (CPDF_Object*)PDFOBJ_DICTIONARY; | 2166 return (CPDF_Object*)PDFOBJ_DICTIONARY; |
| 2154 } | 2167 |
| 2155 if (pContext) { | 2168 if (pContext) |
| 2156 pContext->m_DictStart = SavedPos; | 2169 pContext->m_DictStart = SavedPos; |
| 2157 } | 2170 |
| 2158 CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); | |
| 2159 int32_t nKeys = 0; | 2171 int32_t nKeys = 0; |
| 2160 FX_FILESIZE dwSignValuePos = 0; | 2172 FX_FILESIZE dwSignValuePos = 0; |
| 2173 nonstd::unique_ptr<CPDF_Dictionary, ReleaseDeleter<CPDF_Dictionary>> pDict( |
| 2174 CPDF_Dictionary::Create()); |
| 2161 while (1) { | 2175 while (1) { |
| 2162 FX_BOOL bIsNumber; | 2176 FX_BOOL bIsNumber; |
| 2163 CFX_ByteString key = GetNextWord(bIsNumber); | 2177 CFX_ByteString key = GetNextWord(bIsNumber); |
| 2164 if (key.IsEmpty()) { | 2178 if (key.IsEmpty()) |
| 2165 if (pDict) | 2179 return nullptr; |
| 2166 pDict->Release(); | 2180 |
| 2167 return NULL; | |
| 2168 } | |
| 2169 FX_FILESIZE SavedPos = m_Pos - key.GetLength(); | 2181 FX_FILESIZE SavedPos = m_Pos - key.GetLength(); |
| 2170 if (key == FX_BSTRC(">>")) { | 2182 if (key == FX_BSTRC(">>")) |
| 2171 break; | 2183 break; |
| 2172 } | 2184 |
| 2173 if (key == FX_BSTRC("endobj")) { | 2185 if (key == FX_BSTRC("endobj")) { |
| 2174 m_Pos = SavedPos; | 2186 m_Pos = SavedPos; |
| 2175 break; | 2187 break; |
| 2176 } | 2188 } |
| 2177 if (key[0] != '/') { | 2189 if (key[0] != '/') |
| 2178 continue; | 2190 continue; |
| 2179 } | 2191 |
| 2180 nKeys++; | 2192 ++nKeys; |
| 2181 key = PDF_NameDecode(key); | 2193 key = PDF_NameDecode(key); |
| 2182 if (key == FX_BSTRC("/Contents")) { | 2194 if (key == FX_BSTRC("/Contents")) |
| 2183 dwSignValuePos = m_Pos; | 2195 dwSignValuePos = m_Pos; |
| 2184 } | 2196 |
| 2185 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum); | 2197 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum); |
| 2186 if (pObj == NULL) { | 2198 if (!pObj) |
| 2187 continue; | 2199 continue; |
| 2188 } | 2200 |
| 2189 if (key.GetLength() >= 1) { | 2201 if (key.GetLength() >= 1) { |
| 2190 if (nKeys < 32) { | 2202 if (nKeys < 32) { |
| 2191 pDict->SetAt(CFX_ByteStringC(key.c_str() + 1, key.GetLength() - 1), | 2203 pDict->SetAt(CFX_ByteStringC(key.c_str() + 1, key.GetLength() - 1), |
| 2192 pObj); | 2204 pObj); |
| 2193 } else { | 2205 } else { |
| 2194 pDict->AddValue(CFX_ByteStringC(key.c_str() + 1, key.GetLength() - 1), | 2206 pDict->AddValue(CFX_ByteStringC(key.c_str() + 1, key.GetLength() - 1), |
| 2195 pObj); | 2207 pObj); |
| 2196 } | 2208 } |
| 2197 } | 2209 } |
| 2198 } | 2210 } |
| 2199 if (IsSignatureDict(pDict)) { | 2211 |
| 2212 if (IsSignatureDict(pDict.get())) { |
| 2200 FX_FILESIZE dwSavePos = m_Pos; | 2213 FX_FILESIZE dwSavePos = m_Pos; |
| 2201 m_Pos = dwSignValuePos; | 2214 m_Pos = dwSignValuePos; |
| 2202 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, NULL, FALSE); | 2215 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, NULL, FALSE); |
| 2203 pDict->SetAt(FX_BSTRC("Contents"), pObj); | 2216 pDict->SetAt(FX_BSTRC("Contents"), pObj); |
| 2204 m_Pos = dwSavePos; | 2217 m_Pos = dwSavePos; |
| 2205 } | 2218 } |
| 2206 if (pContext) { | 2219 if (pContext) { |
| 2207 pContext->m_DictEnd = m_Pos; | 2220 pContext->m_DictEnd = m_Pos; |
| 2208 if (pContext->m_Flags & PDFPARSE_NOSTREAM) { | 2221 if (pContext->m_Flags & PDFPARSE_NOSTREAM) { |
| 2209 return pDict; | 2222 return pDict.release(); |
| 2210 } | 2223 } |
| 2211 } | 2224 } |
| 2212 FX_FILESIZE SavedPos = m_Pos; | 2225 FX_FILESIZE SavedPos = m_Pos; |
| 2213 FX_BOOL bIsNumber; | 2226 FX_BOOL bIsNumber; |
| 2214 CFX_ByteString nextword = GetNextWord(bIsNumber); | 2227 CFX_ByteString nextword = GetNextWord(bIsNumber); |
| 2215 if (nextword == FX_BSTRC("stream")) { | 2228 if (nextword != FX_BSTRC("stream")) { |
| 2216 CPDF_Stream* pStream = ReadStream(pDict, pContext, objnum, gennum); | |
| 2217 if (pStream) { | |
| 2218 return pStream; | |
| 2219 } | |
| 2220 if (pDict) | |
| 2221 pDict->Release(); | |
| 2222 return NULL; | |
| 2223 } else { | |
| 2224 m_Pos = SavedPos; | 2229 m_Pos = SavedPos; |
| 2225 return pDict; | 2230 return pDict.release(); |
| 2226 } | 2231 } |
| 2232 |
| 2233 return ReadStream(pDict.release(), pContext, objnum, gennum); |
| 2227 } | 2234 } |
| 2228 if (word == FX_BSTRC(">>")) { | 2235 if (word == FX_BSTRC(">>")) { |
| 2229 m_Pos = SavedPos; | 2236 m_Pos = SavedPos; |
| 2230 return NULL; | 2237 return nullptr; |
| 2231 } | 2238 } |
| 2232 if (bTypeOnly) { | 2239 if (bTypeOnly) |
| 2233 return (CPDF_Object*)PDFOBJ_INVALID; | 2240 return (CPDF_Object*)PDFOBJ_INVALID; |
| 2234 } | 2241 |
| 2235 return NULL; | 2242 return nullptr; |
| 2236 } | 2243 } |
| 2244 |
| 2237 CPDF_Object* CPDF_SyntaxParser::GetObjectByStrict( | 2245 CPDF_Object* CPDF_SyntaxParser::GetObjectByStrict( |
| 2238 CPDF_IndirectObjects* pObjList, | 2246 CPDF_IndirectObjects* pObjList, |
| 2239 FX_DWORD objnum, | 2247 FX_DWORD objnum, |
| 2240 FX_DWORD gennum, | 2248 FX_DWORD gennum, |
| 2241 struct PARSE_CONTEXT* pContext) { | 2249 struct PARSE_CONTEXT* pContext) { |
| 2242 CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth); | 2250 CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth); |
| 2243 if (++s_CurrentRecursionDepth > kParserMaxRecursionDepth) { | 2251 if (++s_CurrentRecursionDepth > kParserMaxRecursionDepth) { |
| 2244 return NULL; | 2252 return NULL; |
| 2245 } | 2253 } |
| 2246 FX_FILESIZE SavedPos = m_Pos; | 2254 FX_FILESIZE SavedPos = m_Pos; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2301 CFX_ByteString str = ReadHexString(); | 2309 CFX_ByteString str = ReadHexString(); |
| 2302 if (m_pCryptoHandler) { | 2310 if (m_pCryptoHandler) { |
| 2303 m_pCryptoHandler->Decrypt(objnum, gennum, str); | 2311 m_pCryptoHandler->Decrypt(objnum, gennum, str); |
| 2304 } | 2312 } |
| 2305 return CPDF_String::Create(str, TRUE); | 2313 return CPDF_String::Create(str, TRUE); |
| 2306 } | 2314 } |
| 2307 if (word == FX_BSTRC("[")) { | 2315 if (word == FX_BSTRC("[")) { |
| 2308 if (bTypeOnly) { | 2316 if (bTypeOnly) { |
| 2309 return (CPDF_Object*)PDFOBJ_ARRAY; | 2317 return (CPDF_Object*)PDFOBJ_ARRAY; |
| 2310 } | 2318 } |
| 2311 CPDF_Array* pArray = CPDF_Array::Create(); | 2319 nonstd::unique_ptr<CPDF_Array, ReleaseDeleter<CPDF_Array>> pArray( |
| 2312 while (1) { | 2320 CPDF_Array::Create()); |
| 2313 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum); | 2321 while (CPDF_Object* pObj = GetObject(pObjList, objnum, gennum)) |
| 2314 if (pObj == NULL) { | |
| 2315 if (m_WordBuffer[0] == ']') { | |
| 2316 return pArray; | |
| 2317 } | |
| 2318 if (pArray) { | |
| 2319 pArray->Release(); | |
| 2320 } | |
| 2321 return NULL; | |
| 2322 } | |
| 2323 pArray->Add(pObj); | 2322 pArray->Add(pObj); |
| 2324 } | 2323 return m_WordBuffer[0] == ']' ? pArray.release() : nullptr; |
| 2325 } | 2324 } |
| 2326 if (word[0] == '/') { | 2325 if (word[0] == '/') { |
| 2327 if (bTypeOnly) { | 2326 if (bTypeOnly) { |
| 2328 return (CPDF_Object*)PDFOBJ_NAME; | 2327 return (CPDF_Object*)PDFOBJ_NAME; |
| 2329 } | 2328 } |
| 2330 return CPDF_Name::Create( | 2329 return CPDF_Name::Create( |
| 2331 PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))); | 2330 PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))); |
| 2332 } | 2331 } |
| 2333 if (word == FX_BSTRC("<<")) { | 2332 if (word == FX_BSTRC("<<")) { |
| 2334 if (bTypeOnly) { | 2333 if (bTypeOnly) { |
| 2335 return (CPDF_Object*)PDFOBJ_DICTIONARY; | 2334 return (CPDF_Object*)PDFOBJ_DICTIONARY; |
| 2336 } | 2335 } |
| 2337 if (pContext) { | 2336 if (pContext) { |
| 2338 pContext->m_DictStart = SavedPos; | 2337 pContext->m_DictStart = SavedPos; |
| 2339 } | 2338 } |
| 2340 CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); | 2339 nonstd::unique_ptr<CPDF_Dictionary, ReleaseDeleter<CPDF_Dictionary>> pDict( |
| 2340 CPDF_Dictionary::Create()); |
| 2341 while (1) { | 2341 while (1) { |
| 2342 FX_BOOL bIsNumber; | 2342 FX_BOOL bIsNumber; |
| 2343 FX_FILESIZE SavedPos = m_Pos; | 2343 FX_FILESIZE SavedPos = m_Pos; |
| 2344 CFX_ByteString key = GetNextWord(bIsNumber); | 2344 CFX_ByteString key = GetNextWord(bIsNumber); |
| 2345 if (key.IsEmpty()) { | 2345 if (key.IsEmpty()) |
| 2346 if (pDict) { | 2346 return nullptr; |
| 2347 pDict->Release(); | 2347 |
| 2348 } | 2348 if (key == FX_BSTRC(">>")) |
| 2349 return NULL; | |
| 2350 } | |
| 2351 if (key == FX_BSTRC(">>")) { | |
| 2352 break; | 2349 break; |
| 2353 } | 2350 |
| 2354 if (key == FX_BSTRC("endobj")) { | 2351 if (key == FX_BSTRC("endobj")) { |
| 2355 m_Pos = SavedPos; | 2352 m_Pos = SavedPos; |
| 2356 break; | 2353 break; |
| 2357 } | 2354 } |
| 2358 if (key[0] != '/') { | 2355 if (key[0] != '/') |
| 2359 continue; | 2356 continue; |
| 2360 } | 2357 |
| 2361 key = PDF_NameDecode(key); | 2358 key = PDF_NameDecode(key); |
| 2362 nonstd::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>> obj( | 2359 nonstd::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>> obj( |
| 2363 GetObject(pObjList, objnum, gennum)); | 2360 GetObject(pObjList, objnum, gennum)); |
| 2364 if (!obj) { | 2361 if (!obj) { |
| 2365 if (pDict) { | 2362 uint8_t ch; |
| 2366 pDict->Release(); | 2363 while (GetNextChar(ch) && ch != 0x0A && ch != 0x0D) { |
| 2367 } | 2364 } |
| 2368 uint8_t ch; | 2365 return nullptr; |
| 2369 while (1) { | |
| 2370 if (!GetNextChar(ch)) { | |
| 2371 break; | |
| 2372 } | |
| 2373 if (ch == 0x0A || ch == 0x0D) { | |
| 2374 break; | |
| 2375 } | |
| 2376 } | |
| 2377 return NULL; | |
| 2378 } | 2366 } |
| 2379 if (key.GetLength() > 1) { | 2367 if (key.GetLength() > 1) { |
| 2380 pDict->AddValue(CFX_ByteStringC(key.c_str() + 1, key.GetLength() - 1), | 2368 pDict->AddValue(CFX_ByteStringC(key.c_str() + 1, key.GetLength() - 1), |
| 2381 obj.release()); | 2369 obj.release()); |
| 2382 } | 2370 } |
| 2383 } | 2371 } |
| 2384 if (pContext) { | 2372 if (pContext) { |
| 2385 pContext->m_DictEnd = m_Pos; | 2373 pContext->m_DictEnd = m_Pos; |
| 2386 if (pContext->m_Flags & PDFPARSE_NOSTREAM) { | 2374 if (pContext->m_Flags & PDFPARSE_NOSTREAM) { |
| 2387 return pDict; | 2375 return pDict.release(); |
| 2388 } | 2376 } |
| 2389 } | 2377 } |
| 2390 FX_FILESIZE SavedPos = m_Pos; | 2378 FX_FILESIZE SavedPos = m_Pos; |
| 2391 FX_BOOL bIsNumber; | 2379 FX_BOOL bIsNumber; |
| 2392 CFX_ByteString nextword = GetNextWord(bIsNumber); | 2380 CFX_ByteString nextword = GetNextWord(bIsNumber); |
| 2393 if (nextword == FX_BSTRC("stream")) { | 2381 if (nextword != FX_BSTRC("stream")) { |
| 2394 CPDF_Stream* pStream = ReadStream(pDict, pContext, objnum, gennum); | |
| 2395 if (pStream) { | |
| 2396 return pStream; | |
| 2397 } | |
| 2398 if (pDict) { | |
| 2399 pDict->Release(); | |
| 2400 } | |
| 2401 return NULL; | |
| 2402 } else { | |
| 2403 m_Pos = SavedPos; | 2382 m_Pos = SavedPos; |
| 2404 return pDict; | 2383 return pDict.release(); |
| 2405 } | 2384 } |
| 2385 |
| 2386 return ReadStream(pDict.release(), pContext, objnum, gennum); |
| 2406 } | 2387 } |
| 2407 if (word == FX_BSTRC(">>")) { | 2388 if (word == FX_BSTRC(">>")) { |
| 2408 m_Pos = SavedPos; | 2389 m_Pos = SavedPos; |
| 2409 return NULL; | 2390 return nullptr; |
| 2410 } | 2391 } |
| 2411 if (bTypeOnly) { | 2392 if (bTypeOnly) |
| 2412 return (CPDF_Object*)PDFOBJ_INVALID; | 2393 return (CPDF_Object*)PDFOBJ_INVALID; |
| 2413 } | 2394 |
| 2414 return NULL; | 2395 return nullptr; |
| 2415 } | 2396 } |
| 2397 |
| 2416 unsigned int CPDF_SyntaxParser::ReadEOLMarkers(FX_FILESIZE pos) { | 2398 unsigned int CPDF_SyntaxParser::ReadEOLMarkers(FX_FILESIZE pos) { |
| 2417 unsigned char byte1 = 0; | 2399 unsigned char byte1 = 0; |
| 2418 unsigned char byte2 = 0; | 2400 unsigned char byte2 = 0; |
| 2419 GetCharAt(pos, byte1); | 2401 GetCharAt(pos, byte1); |
| 2420 GetCharAt(pos + 1, byte2); | 2402 GetCharAt(pos + 1, byte2); |
| 2421 unsigned int markers = 0; | 2403 unsigned int markers = 0; |
| 2422 if (byte1 == '\r' && byte2 == '\n') { | 2404 if (byte1 == '\r' && byte2 == '\n') { |
| 2423 markers = 2; | 2405 markers = 2; |
| 2424 } else if (byte1 == '\r' || byte1 == '\n') { | 2406 } else if (byte1 == '\r' || byte1 == '\n') { |
| 2425 markers = 1; | 2407 markers = 1; |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2669 offset = byte == tag_data[taglen - 1] ? taglen - 2 : taglen - 1; | 2651 offset = byte == tag_data[taglen - 1] ? taglen - 2 : taglen - 1; |
| 2670 pos--; | 2652 pos--; |
| 2671 } | 2653 } |
| 2672 if (pos < 0) { | 2654 if (pos < 0) { |
| 2673 return FALSE; | 2655 return FALSE; |
| 2674 } | 2656 } |
| 2675 } | 2657 } |
| 2676 return FALSE; | 2658 return FALSE; |
| 2677 } | 2659 } |
| 2678 | 2660 |
| 2679 struct _SearchTagRecord { | |
| 2680 const uint8_t* m_pTag; | |
| 2681 FX_DWORD m_Len; | |
| 2682 FX_DWORD m_Offset; | |
| 2683 }; | |
| 2684 | |
| 2685 int32_t CPDF_SyntaxParser::SearchMultiWord(const CFX_ByteStringC& tags, | 2661 int32_t CPDF_SyntaxParser::SearchMultiWord(const CFX_ByteStringC& tags, |
| 2686 FX_BOOL bWholeWord, | 2662 FX_BOOL bWholeWord, |
| 2687 FX_FILESIZE limit) { | 2663 FX_FILESIZE limit) { |
| 2688 int32_t ntags = 1; | 2664 int32_t ntags = 1; |
| 2689 for (int i = 0; i < tags.GetLength(); ++i) { | 2665 for (int i = 0; i < tags.GetLength(); ++i) { |
| 2690 if (tags[i] == 0) { | 2666 if (tags[i] == 0) { |
| 2691 ++ntags; | 2667 ++ntags; |
| 2692 } | 2668 } |
| 2693 } | 2669 } |
| 2694 | 2670 |
| 2695 std::vector<_SearchTagRecord> patterns(ntags); | 2671 std::vector<SearchTagRecord> patterns(ntags); |
| 2696 FX_DWORD start = 0; | 2672 FX_DWORD start = 0; |
| 2697 FX_DWORD itag = 0; | 2673 FX_DWORD itag = 0; |
| 2698 FX_DWORD max_len = 0; | 2674 FX_DWORD max_len = 0; |
| 2699 for (int i = 0; i <= tags.GetLength(); ++i) { | 2675 for (int i = 0; i <= tags.GetLength(); ++i) { |
| 2700 if (tags[i] == 0) { | 2676 if (tags[i] == 0) { |
| 2701 FX_DWORD len = i - start; | 2677 FX_DWORD len = i - start; |
| 2702 max_len = std::max(len, max_len); | 2678 max_len = std::max(len, max_len); |
| 2703 patterns[itag].m_pTag = tags.GetPtr() + start; | 2679 patterns[itag].m_pTag = tags.GetPtr() + start; |
| 2704 patterns[itag].m_Len = len; | 2680 patterns[itag].m_Len = len; |
| 2705 patterns[itag].m_Offset = 0; | 2681 patterns[itag].m_Offset = 0; |
| 2706 start = i + 1; | 2682 start = i + 1; |
| 2707 ++itag; | 2683 ++itag; |
| 2708 } | 2684 } |
| 2709 } | 2685 } |
| 2710 | 2686 |
| 2711 const FX_FILESIZE pos_limit = m_Pos + limit; | 2687 const FX_FILESIZE pos_limit = m_Pos + limit; |
| 2712 for (FX_FILESIZE pos = m_Pos; !limit || pos < pos_limit; ++pos) { | 2688 for (FX_FILESIZE pos = m_Pos; !limit || pos < pos_limit; ++pos) { |
| 2713 uint8_t byte; | 2689 uint8_t byte; |
| 2714 if (!GetCharAt(pos, byte)) | 2690 if (!GetCharAt(pos, byte)) |
| 2715 break; | 2691 break; |
| 2716 | 2692 |
| 2717 for (int i = 0; i < ntags; ++i) { | 2693 for (int i = 0; i < ntags; ++i) { |
| 2718 _SearchTagRecord& pat = patterns[i]; | 2694 SearchTagRecord& pat = patterns[i]; |
| 2719 if (pat.m_pTag[pat.m_Offset] != byte) { | 2695 if (pat.m_pTag[pat.m_Offset] != byte) { |
| 2720 pat.m_Offset = (pat.m_pTag[0] == byte) ? 1 : 0; | 2696 pat.m_Offset = (pat.m_pTag[0] == byte) ? 1 : 0; |
| 2721 continue; | 2697 continue; |
| 2722 } | 2698 } |
| 2723 | 2699 |
| 2724 ++pat.m_Offset; | 2700 ++pat.m_Offset; |
| 2725 if (pat.m_Offset != pat.m_Len) | 2701 if (pat.m_Offset != pat.m_Len) |
| 2726 continue; | 2702 continue; |
| 2727 | 2703 |
| 2728 if (!bWholeWord || | 2704 if (!bWholeWord || |
| (...skipping 998 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3727 return PDF_UNKNOW_LINEARIZED; | 3703 return PDF_UNKNOW_LINEARIZED; |
| 3728 } | 3704 } |
| 3729 uint8_t buffer[1024]; | 3705 uint8_t buffer[1024]; |
| 3730 m_pFileRead->ReadBlock(buffer, 0, req_size); | 3706 m_pFileRead->ReadBlock(buffer, 0, req_size); |
| 3731 if (IsLinearizedFile(buffer, req_size)) { | 3707 if (IsLinearizedFile(buffer, req_size)) { |
| 3732 return PDF_IS_LINEARIZED; | 3708 return PDF_IS_LINEARIZED; |
| 3733 } | 3709 } |
| 3734 return PDF_NOT_LINEARIZED; | 3710 return PDF_NOT_LINEARIZED; |
| 3735 } | 3711 } |
| 3736 FX_BOOL CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen) { | 3712 FX_BOOL CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen) { |
| 3737 CFX_SmartPointer<IFX_FileStream> file( | 3713 ScopedFileStream file(FX_CreateMemoryStream(pData, (size_t)dwLen, FALSE)); |
| 3738 FX_CreateMemoryStream(pData, (size_t)dwLen, FALSE)); | 3714 int32_t offset = GetHeaderOffset(file.get()); |
| 3739 int32_t offset = GetHeaderOffset(file.Get()); | |
| 3740 if (offset == -1) { | 3715 if (offset == -1) { |
| 3741 m_docStatus = PDF_DATAAVAIL_ERROR; | 3716 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 3742 return FALSE; | 3717 return FALSE; |
| 3743 } | 3718 } |
| 3744 m_dwHeaderOffset = offset; | 3719 m_dwHeaderOffset = offset; |
| 3745 m_syntaxParser.InitParser(file.Get(), offset); | 3720 m_syntaxParser.InitParser(file.get(), offset); |
| 3746 m_syntaxParser.RestorePos(m_syntaxParser.m_HeaderOffset + 9); | 3721 m_syntaxParser.RestorePos(m_syntaxParser.m_HeaderOffset + 9); |
| 3747 FX_BOOL bNumber = FALSE; | 3722 FX_BOOL bNumber = FALSE; |
| 3748 CFX_ByteString wordObjNum = m_syntaxParser.GetNextWord(bNumber); | 3723 CFX_ByteString wordObjNum = m_syntaxParser.GetNextWord(bNumber); |
| 3749 if (!bNumber) { | 3724 if (!bNumber) { |
| 3750 return FALSE; | 3725 return FALSE; |
| 3751 } | 3726 } |
| 3752 FX_DWORD objnum = FXSYS_atoi(wordObjNum); | 3727 FX_DWORD objnum = FXSYS_atoi(wordObjNum); |
| 3753 if (m_pLinearized) { | 3728 if (m_pLinearized) { |
| 3754 m_pLinearized->Release(); | 3729 m_pLinearized->Release(); |
| 3755 m_pLinearized = NULL; | 3730 m_pLinearized = NULL; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 3776 return TRUE; | 3751 return TRUE; |
| 3777 } | 3752 } |
| 3778 return FALSE; | 3753 return FALSE; |
| 3779 } | 3754 } |
| 3780 FX_BOOL CPDF_DataAvail::CheckEnd(IFX_DownloadHints* pHints) { | 3755 FX_BOOL CPDF_DataAvail::CheckEnd(IFX_DownloadHints* pHints) { |
| 3781 FX_DWORD req_pos = (FX_DWORD)(m_dwFileLen > 1024 ? m_dwFileLen - 1024 : 0); | 3756 FX_DWORD req_pos = (FX_DWORD)(m_dwFileLen > 1024 ? m_dwFileLen - 1024 : 0); |
| 3782 FX_DWORD dwSize = (FX_DWORD)(m_dwFileLen - req_pos); | 3757 FX_DWORD dwSize = (FX_DWORD)(m_dwFileLen - req_pos); |
| 3783 if (m_pFileAvail->IsDataAvail(req_pos, dwSize)) { | 3758 if (m_pFileAvail->IsDataAvail(req_pos, dwSize)) { |
| 3784 uint8_t buffer[1024]; | 3759 uint8_t buffer[1024]; |
| 3785 m_pFileRead->ReadBlock(buffer, req_pos, dwSize); | 3760 m_pFileRead->ReadBlock(buffer, req_pos, dwSize); |
| 3786 CFX_SmartPointer<IFX_FileStream> file( | 3761 ScopedFileStream file(FX_CreateMemoryStream(buffer, (size_t)dwSize, FALSE)); |
| 3787 FX_CreateMemoryStream(buffer, (size_t)dwSize, FALSE)); | 3762 m_syntaxParser.InitParser(file.get(), 0); |
| 3788 m_syntaxParser.InitParser(file.Get(), 0); | |
| 3789 m_syntaxParser.RestorePos(dwSize - 1); | 3763 m_syntaxParser.RestorePos(dwSize - 1); |
| 3790 if (m_syntaxParser.SearchWord(FX_BSTRC("startxref"), TRUE, FALSE, dwSize)) { | 3764 if (m_syntaxParser.SearchWord(FX_BSTRC("startxref"), TRUE, FALSE, dwSize)) { |
| 3791 FX_BOOL bNumber; | 3765 FX_BOOL bNumber; |
| 3792 m_syntaxParser.GetNextWord(bNumber); | 3766 m_syntaxParser.GetNextWord(bNumber); |
| 3793 CFX_ByteString xrefpos_str = m_syntaxParser.GetNextWord(bNumber); | 3767 CFX_ByteString xrefpos_str = m_syntaxParser.GetNextWord(bNumber); |
| 3794 if (!bNumber) { | 3768 if (!bNumber) { |
| 3795 m_docStatus = PDF_DATAAVAIL_ERROR; | 3769 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 3796 return FALSE; | 3770 return FALSE; |
| 3797 } | 3771 } |
| 3798 m_dwXRefOffset = (FX_FILESIZE)FXSYS_atoi64(xrefpos_str); | 3772 m_dwXRefOffset = (FX_FILESIZE)FXSYS_atoi64(xrefpos_str); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3814 int32_t CPDF_DataAvail::CheckCrossRefStream(IFX_DownloadHints* pHints, | 3788 int32_t CPDF_DataAvail::CheckCrossRefStream(IFX_DownloadHints* pHints, |
| 3815 FX_FILESIZE& xref_offset) { | 3789 FX_FILESIZE& xref_offset) { |
| 3816 xref_offset = 0; | 3790 xref_offset = 0; |
| 3817 FX_DWORD req_size = | 3791 FX_DWORD req_size = |
| 3818 (FX_DWORD)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512); | 3792 (FX_DWORD)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512); |
| 3819 if (m_pFileAvail->IsDataAvail(m_Pos, req_size)) { | 3793 if (m_pFileAvail->IsDataAvail(m_Pos, req_size)) { |
| 3820 int32_t iSize = (int32_t)(m_Pos + req_size - m_dwCurrentXRefSteam); | 3794 int32_t iSize = (int32_t)(m_Pos + req_size - m_dwCurrentXRefSteam); |
| 3821 CFX_BinaryBuf buf(iSize); | 3795 CFX_BinaryBuf buf(iSize); |
| 3822 uint8_t* pBuf = buf.GetBuffer(); | 3796 uint8_t* pBuf = buf.GetBuffer(); |
| 3823 m_pFileRead->ReadBlock(pBuf, m_dwCurrentXRefSteam, iSize); | 3797 m_pFileRead->ReadBlock(pBuf, m_dwCurrentXRefSteam, iSize); |
| 3824 CFX_SmartPointer<IFX_FileStream> file( | 3798 ScopedFileStream file(FX_CreateMemoryStream(pBuf, (size_t)iSize, FALSE)); |
| 3825 FX_CreateMemoryStream(pBuf, (size_t)iSize, FALSE)); | 3799 m_parser.m_Syntax.InitParser(file.get(), 0); |
| 3826 m_parser.m_Syntax.InitParser(file.Get(), 0); | |
| 3827 FX_BOOL bNumber = FALSE; | 3800 FX_BOOL bNumber = FALSE; |
| 3828 CFX_ByteString objnum = m_parser.m_Syntax.GetNextWord(bNumber); | 3801 CFX_ByteString objnum = m_parser.m_Syntax.GetNextWord(bNumber); |
| 3829 if (!bNumber) { | 3802 if (!bNumber) { |
| 3830 return -1; | 3803 return -1; |
| 3831 } | 3804 } |
| 3832 FX_DWORD objNum = FXSYS_atoi(objnum); | 3805 FX_DWORD objNum = FXSYS_atoi(objnum); |
| 3833 CPDF_Object* pObj = m_parser.ParseIndirectObjectAt(NULL, 0, objNum, NULL); | 3806 CPDF_Object* pObj = m_parser.ParseIndirectObjectAt(NULL, 0, objNum, NULL); |
| 3834 if (!pObj) { | 3807 if (!pObj) { |
| 3835 m_Pos += m_parser.m_Syntax.SavePos(); | 3808 m_Pos += m_parser.m_Syntax.SavePos(); |
| 3836 return 0; | 3809 return 0; |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4054 int32_t iSize = (int32_t)(m_Pos + iTrailerSize - m_dwTrailerOffset); | 4027 int32_t iSize = (int32_t)(m_Pos + iTrailerSize - m_dwTrailerOffset); |
| 4055 CFX_BinaryBuf buf(iSize); | 4028 CFX_BinaryBuf buf(iSize); |
| 4056 uint8_t* pBuf = buf.GetBuffer(); | 4029 uint8_t* pBuf = buf.GetBuffer(); |
| 4057 if (!pBuf) { | 4030 if (!pBuf) { |
| 4058 m_docStatus = PDF_DATAAVAIL_ERROR; | 4031 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 4059 return FALSE; | 4032 return FALSE; |
| 4060 } | 4033 } |
| 4061 if (!m_pFileRead->ReadBlock(pBuf, m_dwTrailerOffset, iSize)) { | 4034 if (!m_pFileRead->ReadBlock(pBuf, m_dwTrailerOffset, iSize)) { |
| 4062 return FALSE; | 4035 return FALSE; |
| 4063 } | 4036 } |
| 4064 CFX_SmartPointer<IFX_FileStream> file( | 4037 ScopedFileStream file(FX_CreateMemoryStream(pBuf, (size_t)iSize, FALSE)); |
| 4065 FX_CreateMemoryStream(pBuf, (size_t)iSize, FALSE)); | 4038 m_syntaxParser.InitParser(file.get(), 0); |
| 4066 m_syntaxParser.InitParser(file.Get(), 0); | 4039 nonstd::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>> pTrailer( |
| 4067 CPDF_Object* pTrailer = m_syntaxParser.GetObject(nullptr, 0, 0); | 4040 m_syntaxParser.GetObject(nullptr, 0, 0)); |
| 4068 if (!pTrailer) { | 4041 if (!pTrailer) { |
| 4069 m_Pos += m_syntaxParser.SavePos(); | 4042 m_Pos += m_syntaxParser.SavePos(); |
| 4070 pHints->AddSegment(m_Pos, iTrailerSize); | 4043 pHints->AddSegment(m_Pos, iTrailerSize); |
| 4071 return FALSE; | 4044 return FALSE; |
| 4072 } | 4045 } |
| 4073 if (pTrailer->GetType() != PDFOBJ_DICTIONARY) { | 4046 if (pTrailer->GetType() != PDFOBJ_DICTIONARY) |
| 4074 pTrailer->Release(); | |
| 4075 return FALSE; | 4047 return FALSE; |
| 4076 } | 4048 |
| 4077 CPDF_Dictionary* pTrailerDict = pTrailer->GetDict(); | 4049 CPDF_Dictionary* pTrailerDict = pTrailer->GetDict(); |
| 4078 CPDF_Object* pEncrypt = pTrailerDict->GetElement("Encrypt"); | 4050 CPDF_Object* pEncrypt = pTrailerDict->GetElement("Encrypt"); |
| 4079 if (pEncrypt && pEncrypt->GetType() == PDFOBJ_REFERENCE) { | 4051 if (pEncrypt && pEncrypt->GetType() == PDFOBJ_REFERENCE) { |
| 4080 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; | 4052 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; |
| 4081 pTrailer->Release(); | |
| 4082 return TRUE; | 4053 return TRUE; |
| 4083 } | 4054 } |
| 4084 FX_DWORD xrefpos = GetDirectInteger(pTrailer->GetDict(), FX_BSTRC("Prev")); | 4055 |
| 4056 FX_DWORD xrefpos = GetDirectInteger(pTrailerDict, FX_BSTRC("Prev")); |
| 4085 if (xrefpos) { | 4057 if (xrefpos) { |
| 4086 m_dwPrevXRefOffset = | 4058 m_dwPrevXRefOffset = GetDirectInteger(pTrailerDict, FX_BSTRC("XRefStm")); |
| 4087 GetDirectInteger(pTrailer->GetDict(), FX_BSTRC("XRefStm")); | |
| 4088 pTrailer->Release(); | |
| 4089 if (m_dwPrevXRefOffset) { | 4059 if (m_dwPrevXRefOffset) { |
| 4090 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; | 4060 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; |
| 4091 } else { | 4061 } else { |
| 4092 m_dwPrevXRefOffset = xrefpos; | 4062 m_dwPrevXRefOffset = xrefpos; |
| 4093 if (m_dwPrevXRefOffset >= m_dwFileLen) { | 4063 if (m_dwPrevXRefOffset >= m_dwFileLen) { |
| 4094 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; | 4064 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; |
| 4095 } else { | 4065 } else { |
| 4096 SetStartOffset(m_dwPrevXRefOffset); | 4066 SetStartOffset(m_dwPrevXRefOffset); |
| 4097 m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND; | 4067 m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND; |
| 4098 } | 4068 } |
| 4099 } | 4069 } |
| 4100 return TRUE; | 4070 return TRUE; |
| 4101 } | 4071 } |
| 4102 m_dwPrevXRefOffset = 0; | 4072 m_dwPrevXRefOffset = 0; |
| 4103 m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND; | 4073 m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND; |
| 4104 pTrailer->Release(); | |
| 4105 return TRUE; | 4074 return TRUE; |
| 4106 } | 4075 } |
| 4107 pHints->AddSegment(m_Pos, iTrailerSize); | 4076 pHints->AddSegment(m_Pos, iTrailerSize); |
| 4108 return FALSE; | 4077 return FALSE; |
| 4109 } | 4078 } |
| 4110 | 4079 |
| 4111 FX_BOOL CPDF_DataAvail::CheckPage(int32_t iPage, IFX_DownloadHints* pHints) { | 4080 FX_BOOL CPDF_DataAvail::CheckPage(int32_t iPage, IFX_DownloadHints* pHints) { |
| 4112 while (TRUE) { | 4081 while (TRUE) { |
| 4113 switch (m_docStatus) { | 4082 switch (m_docStatus) { |
| 4114 case PDF_DATAAVAIL_PAGETREE: | 4083 case PDF_DATAAVAIL_PAGETREE: |
| (...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4648 return FALSE; | 4617 return FALSE; |
| 4649 } | 4618 } |
| 4650 CPDF_PageNode::~CPDF_PageNode() { | 4619 CPDF_PageNode::~CPDF_PageNode() { |
| 4651 int32_t iSize = m_childNode.GetSize(); | 4620 int32_t iSize = m_childNode.GetSize(); |
| 4652 for (int32_t i = 0; i < iSize; ++i) { | 4621 for (int32_t i = 0; i < iSize; ++i) { |
| 4653 CPDF_PageNode* pNode = (CPDF_PageNode*)m_childNode[i]; | 4622 CPDF_PageNode* pNode = (CPDF_PageNode*)m_childNode[i]; |
| 4654 delete pNode; | 4623 delete pNode; |
| 4655 } | 4624 } |
| 4656 m_childNode.RemoveAll(); | 4625 m_childNode.RemoveAll(); |
| 4657 } | 4626 } |
| OLD | NEW |