| 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 639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2131 m_pCryptoHandler->Decrypt(objnum, gennum, str); | 2147 m_pCryptoHandler->Decrypt(objnum, gennum, str); |
| 2132 } | 2148 } |
| 2133 pRet = CPDF_String::Create(str, TRUE); | 2149 pRet = CPDF_String::Create(str, TRUE); |
| 2134 return pRet; | 2150 return pRet; |
| 2135 } | 2151 } |
| 2136 if (word == FX_BSTRC("[")) { | 2152 if (word == FX_BSTRC("[")) { |
| 2137 if (bTypeOnly) { | 2153 if (bTypeOnly) { |
| 2138 return (CPDF_Object*)PDFOBJ_ARRAY; | 2154 return (CPDF_Object*)PDFOBJ_ARRAY; |
| 2139 } | 2155 } |
| 2140 CPDF_Array* pArray = CPDF_Array::Create(); | 2156 CPDF_Array* pArray = CPDF_Array::Create(); |
| 2141 while (1) { | 2157 while (CPDF_Object* pObj = GetObject(pObjList, objnum, gennum)) |
| 2142 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum); | |
| 2143 if (pObj == NULL) { | |
| 2144 return pArray; | |
| 2145 } | |
| 2146 pArray->Add(pObj); | 2158 pArray->Add(pObj); |
| 2147 } | 2159 |
| 2160 return pArray; |
| 2148 } | 2161 } |
| 2149 if (word[0] == '/') { | 2162 if (word[0] == '/') { |
| 2150 if (bTypeOnly) { | 2163 if (bTypeOnly) { |
| 2151 return (CPDF_Object*)PDFOBJ_NAME; | 2164 return (CPDF_Object*)PDFOBJ_NAME; |
| 2152 } | 2165 } |
| 2153 pRet = CPDF_Name::Create( | 2166 pRet = CPDF_Name::Create( |
| 2154 PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))); | 2167 PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))); |
| 2155 return pRet; | 2168 return pRet; |
| 2156 } | 2169 } |
| 2157 if (word == FX_BSTRC("<<")) { | 2170 if (word == FX_BSTRC("<<")) { |
| 2158 if (bTypeOnly) { | 2171 if (bTypeOnly) |
| 2159 return (CPDF_Object*)PDFOBJ_DICTIONARY; | 2172 return (CPDF_Object*)PDFOBJ_DICTIONARY; |
| 2160 } | 2173 |
| 2161 if (pContext) { | 2174 if (pContext) |
| 2162 pContext->m_DictStart = SavedPos; | 2175 pContext->m_DictStart = SavedPos; |
| 2163 } | 2176 |
| 2164 CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); | |
| 2165 int32_t nKeys = 0; | 2177 int32_t nKeys = 0; |
| 2166 FX_FILESIZE dwSignValuePos = 0; | 2178 FX_FILESIZE dwSignValuePos = 0; |
| 2179 nonstd::unique_ptr<CPDF_Dictionary, ReleaseDeleter<CPDF_Dictionary>> pDict( |
| 2180 CPDF_Dictionary::Create()); |
| 2167 while (1) { | 2181 while (1) { |
| 2168 FX_BOOL bIsNumber; | 2182 FX_BOOL bIsNumber; |
| 2169 CFX_ByteString key = GetNextWord(bIsNumber); | 2183 CFX_ByteString key = GetNextWord(bIsNumber); |
| 2170 if (key.IsEmpty()) { | 2184 if (key.IsEmpty()) |
| 2171 if (pDict) | 2185 return nullptr; |
| 2172 pDict->Release(); | 2186 |
| 2173 return NULL; | |
| 2174 } | |
| 2175 FX_FILESIZE SavedPos = m_Pos - key.GetLength(); | 2187 FX_FILESIZE SavedPos = m_Pos - key.GetLength(); |
| 2176 if (key == FX_BSTRC(">>")) { | 2188 if (key == FX_BSTRC(">>")) |
| 2177 break; | 2189 break; |
| 2178 } | 2190 |
| 2179 if (key == FX_BSTRC("endobj")) { | 2191 if (key == FX_BSTRC("endobj")) { |
| 2180 m_Pos = SavedPos; | 2192 m_Pos = SavedPos; |
| 2181 break; | 2193 break; |
| 2182 } | 2194 } |
| 2183 if (key[0] != '/') { | 2195 if (key[0] != '/') |
| 2184 continue; | 2196 continue; |
| 2185 } | 2197 |
| 2186 nKeys++; | 2198 ++nKeys; |
| 2187 key = PDF_NameDecode(key); | 2199 key = PDF_NameDecode(key); |
| 2188 if (key == FX_BSTRC("/Contents")) { | 2200 if (key == FX_BSTRC("/Contents")) |
| 2189 dwSignValuePos = m_Pos; | 2201 dwSignValuePos = m_Pos; |
| 2190 } | 2202 |
| 2191 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum); | 2203 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum); |
| 2192 if (pObj == NULL) { | 2204 if (!pObj) |
| 2193 continue; | 2205 continue; |
| 2194 } | 2206 |
| 2195 if (key.GetLength() >= 1) { | 2207 if (key.GetLength() >= 1) { |
| 2196 if (nKeys < 32) { | 2208 if (nKeys < 32) { |
| 2197 pDict->SetAt(CFX_ByteStringC(key.c_str() + 1, key.GetLength() - 1), | 2209 pDict->SetAt(CFX_ByteStringC(key.c_str() + 1, key.GetLength() - 1), |
| 2198 pObj); | 2210 pObj); |
| 2199 } else { | 2211 } else { |
| 2200 pDict->AddValue(CFX_ByteStringC(key.c_str() + 1, key.GetLength() - 1), | 2212 pDict->AddValue(CFX_ByteStringC(key.c_str() + 1, key.GetLength() - 1), |
| 2201 pObj); | 2213 pObj); |
| 2202 } | 2214 } |
| 2203 } | 2215 } |
| 2204 } | 2216 } |
| 2205 if (IsSignatureDict(pDict)) { | 2217 |
| 2218 if (IsSignatureDict(pDict.get())) { |
| 2206 FX_FILESIZE dwSavePos = m_Pos; | 2219 FX_FILESIZE dwSavePos = m_Pos; |
| 2207 m_Pos = dwSignValuePos; | 2220 m_Pos = dwSignValuePos; |
| 2208 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, NULL, FALSE); | 2221 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, NULL, FALSE); |
| 2209 pDict->SetAt(FX_BSTRC("Contents"), pObj); | 2222 pDict->SetAt(FX_BSTRC("Contents"), pObj); |
| 2210 m_Pos = dwSavePos; | 2223 m_Pos = dwSavePos; |
| 2211 } | 2224 } |
| 2212 if (pContext) { | 2225 if (pContext) { |
| 2213 pContext->m_DictEnd = m_Pos; | 2226 pContext->m_DictEnd = m_Pos; |
| 2214 if (pContext->m_Flags & PDFPARSE_NOSTREAM) { | 2227 if (pContext->m_Flags & PDFPARSE_NOSTREAM) { |
| 2215 return pDict; | 2228 return pDict.release(); |
| 2216 } | 2229 } |
| 2217 } | 2230 } |
| 2218 FX_FILESIZE SavedPos = m_Pos; | 2231 FX_FILESIZE SavedPos = m_Pos; |
| 2219 FX_BOOL bIsNumber; | 2232 FX_BOOL bIsNumber; |
| 2220 CFX_ByteString nextword = GetNextWord(bIsNumber); | 2233 CFX_ByteString nextword = GetNextWord(bIsNumber); |
| 2221 if (nextword == FX_BSTRC("stream")) { | 2234 if (nextword != FX_BSTRC("stream")) { |
| 2222 CPDF_Stream* pStream = ReadStream(pDict, pContext, objnum, gennum); | |
| 2223 if (pStream) { | |
| 2224 return pStream; | |
| 2225 } | |
| 2226 if (pDict) | |
| 2227 pDict->Release(); | |
| 2228 return NULL; | |
| 2229 } else { | |
| 2230 m_Pos = SavedPos; | 2235 m_Pos = SavedPos; |
| 2231 return pDict; | 2236 return pDict.release(); |
| 2232 } | 2237 } |
| 2238 |
| 2239 return ReadStream(pDict.release(), pContext, objnum, gennum); |
| 2233 } | 2240 } |
| 2234 if (word == FX_BSTRC(">>")) { | 2241 if (word == FX_BSTRC(">>")) { |
| 2235 m_Pos = SavedPos; | 2242 m_Pos = SavedPos; |
| 2236 return NULL; | 2243 return nullptr; |
| 2237 } | 2244 } |
| 2238 if (bTypeOnly) { | 2245 if (bTypeOnly) |
| 2239 return (CPDF_Object*)PDFOBJ_INVALID; | 2246 return (CPDF_Object*)PDFOBJ_INVALID; |
| 2240 } | 2247 |
| 2241 return NULL; | 2248 return nullptr; |
| 2242 } | 2249 } |
| 2250 |
| 2243 CPDF_Object* CPDF_SyntaxParser::GetObjectByStrict( | 2251 CPDF_Object* CPDF_SyntaxParser::GetObjectByStrict( |
| 2244 CPDF_IndirectObjects* pObjList, | 2252 CPDF_IndirectObjects* pObjList, |
| 2245 FX_DWORD objnum, | 2253 FX_DWORD objnum, |
| 2246 FX_DWORD gennum, | 2254 FX_DWORD gennum, |
| 2247 struct PARSE_CONTEXT* pContext) { | 2255 struct PARSE_CONTEXT* pContext) { |
| 2248 CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth); | 2256 CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth); |
| 2249 if (++s_CurrentRecursionDepth > kParserMaxRecursionDepth) { | 2257 if (++s_CurrentRecursionDepth > kParserMaxRecursionDepth) { |
| 2250 return NULL; | 2258 return NULL; |
| 2251 } | 2259 } |
| 2252 FX_FILESIZE SavedPos = m_Pos; | 2260 FX_FILESIZE SavedPos = m_Pos; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2307 CFX_ByteString str = ReadHexString(); | 2315 CFX_ByteString str = ReadHexString(); |
| 2308 if (m_pCryptoHandler) { | 2316 if (m_pCryptoHandler) { |
| 2309 m_pCryptoHandler->Decrypt(objnum, gennum, str); | 2317 m_pCryptoHandler->Decrypt(objnum, gennum, str); |
| 2310 } | 2318 } |
| 2311 return CPDF_String::Create(str, TRUE); | 2319 return CPDF_String::Create(str, TRUE); |
| 2312 } | 2320 } |
| 2313 if (word == FX_BSTRC("[")) { | 2321 if (word == FX_BSTRC("[")) { |
| 2314 if (bTypeOnly) { | 2322 if (bTypeOnly) { |
| 2315 return (CPDF_Object*)PDFOBJ_ARRAY; | 2323 return (CPDF_Object*)PDFOBJ_ARRAY; |
| 2316 } | 2324 } |
| 2317 CPDF_Array* pArray = CPDF_Array::Create(); | 2325 nonstd::unique_ptr<CPDF_Array, ReleaseDeleter<CPDF_Array>> pArray( |
| 2318 while (1) { | 2326 CPDF_Array::Create()); |
| 2319 CPDF_Object* pObj = GetObject(pObjList, objnum, gennum); | 2327 while (CPDF_Object* pObj = GetObject(pObjList, objnum, gennum)) |
| 2320 if (pObj == NULL) { | |
| 2321 if (m_WordBuffer[0] == ']') { | |
| 2322 return pArray; | |
| 2323 } | |
| 2324 if (pArray) { | |
| 2325 pArray->Release(); | |
| 2326 } | |
| 2327 return NULL; | |
| 2328 } | |
| 2329 pArray->Add(pObj); | 2328 pArray->Add(pObj); |
| 2330 } | 2329 return m_WordBuffer[0] == ']' ? pArray.release() : nullptr; |
| 2331 } | 2330 } |
| 2332 if (word[0] == '/') { | 2331 if (word[0] == '/') { |
| 2333 if (bTypeOnly) { | 2332 if (bTypeOnly) { |
| 2334 return (CPDF_Object*)PDFOBJ_NAME; | 2333 return (CPDF_Object*)PDFOBJ_NAME; |
| 2335 } | 2334 } |
| 2336 return CPDF_Name::Create( | 2335 return CPDF_Name::Create( |
| 2337 PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))); | 2336 PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))); |
| 2338 } | 2337 } |
| 2339 if (word == FX_BSTRC("<<")) { | 2338 if (word == FX_BSTRC("<<")) { |
| 2340 if (bTypeOnly) { | 2339 if (bTypeOnly) { |
| 2341 return (CPDF_Object*)PDFOBJ_DICTIONARY; | 2340 return (CPDF_Object*)PDFOBJ_DICTIONARY; |
| 2342 } | 2341 } |
| 2343 if (pContext) { | 2342 if (pContext) { |
| 2344 pContext->m_DictStart = SavedPos; | 2343 pContext->m_DictStart = SavedPos; |
| 2345 } | 2344 } |
| 2346 CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); | 2345 nonstd::unique_ptr<CPDF_Dictionary, ReleaseDeleter<CPDF_Dictionary>> pDict( |
| 2346 CPDF_Dictionary::Create()); |
| 2347 while (1) { | 2347 while (1) { |
| 2348 FX_BOOL bIsNumber; | 2348 FX_BOOL bIsNumber; |
| 2349 FX_FILESIZE SavedPos = m_Pos; | 2349 FX_FILESIZE SavedPos = m_Pos; |
| 2350 CFX_ByteString key = GetNextWord(bIsNumber); | 2350 CFX_ByteString key = GetNextWord(bIsNumber); |
| 2351 if (key.IsEmpty()) { | 2351 if (key.IsEmpty()) |
| 2352 if (pDict) { | 2352 return nullptr; |
| 2353 pDict->Release(); | 2353 |
| 2354 } | 2354 if (key == FX_BSTRC(">>")) |
| 2355 return NULL; | |
| 2356 } | |
| 2357 if (key == FX_BSTRC(">>")) { | |
| 2358 break; | 2355 break; |
| 2359 } | 2356 |
| 2360 if (key == FX_BSTRC("endobj")) { | 2357 if (key == FX_BSTRC("endobj")) { |
| 2361 m_Pos = SavedPos; | 2358 m_Pos = SavedPos; |
| 2362 break; | 2359 break; |
| 2363 } | 2360 } |
| 2364 if (key[0] != '/') { | 2361 if (key[0] != '/') |
| 2365 continue; | 2362 continue; |
| 2366 } | 2363 |
| 2367 key = PDF_NameDecode(key); | 2364 key = PDF_NameDecode(key); |
| 2368 nonstd::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>> obj( | 2365 nonstd::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>> obj( |
| 2369 GetObject(pObjList, objnum, gennum)); | 2366 GetObject(pObjList, objnum, gennum)); |
| 2370 if (!obj) { | 2367 if (!obj) { |
| 2371 if (pDict) { | 2368 uint8_t ch; |
| 2372 pDict->Release(); | 2369 while (GetNextChar(ch) && ch != 0x0A && ch != 0x0D) { |
| 2373 } | 2370 } |
| 2374 uint8_t ch; | 2371 return nullptr; |
| 2375 while (1) { | |
| 2376 if (!GetNextChar(ch)) { | |
| 2377 break; | |
| 2378 } | |
| 2379 if (ch == 0x0A || ch == 0x0D) { | |
| 2380 break; | |
| 2381 } | |
| 2382 } | |
| 2383 return NULL; | |
| 2384 } | 2372 } |
| 2385 if (key.GetLength() > 1) { | 2373 if (key.GetLength() > 1) { |
| 2386 pDict->AddValue(CFX_ByteStringC(key.c_str() + 1, key.GetLength() - 1), | 2374 pDict->AddValue(CFX_ByteStringC(key.c_str() + 1, key.GetLength() - 1), |
| 2387 obj.release()); | 2375 obj.release()); |
| 2388 } | 2376 } |
| 2389 } | 2377 } |
| 2390 if (pContext) { | 2378 if (pContext) { |
| 2391 pContext->m_DictEnd = m_Pos; | 2379 pContext->m_DictEnd = m_Pos; |
| 2392 if (pContext->m_Flags & PDFPARSE_NOSTREAM) { | 2380 if (pContext->m_Flags & PDFPARSE_NOSTREAM) { |
| 2393 return pDict; | 2381 return pDict.release(); |
| 2394 } | 2382 } |
| 2395 } | 2383 } |
| 2396 FX_FILESIZE SavedPos = m_Pos; | 2384 FX_FILESIZE SavedPos = m_Pos; |
| 2397 FX_BOOL bIsNumber; | 2385 FX_BOOL bIsNumber; |
| 2398 CFX_ByteString nextword = GetNextWord(bIsNumber); | 2386 CFX_ByteString nextword = GetNextWord(bIsNumber); |
| 2399 if (nextword == FX_BSTRC("stream")) { | 2387 if (nextword != FX_BSTRC("stream")) { |
| 2400 CPDF_Stream* pStream = ReadStream(pDict, pContext, objnum, gennum); | |
| 2401 if (pStream) { | |
| 2402 return pStream; | |
| 2403 } | |
| 2404 if (pDict) { | |
| 2405 pDict->Release(); | |
| 2406 } | |
| 2407 return NULL; | |
| 2408 } else { | |
| 2409 m_Pos = SavedPos; | 2388 m_Pos = SavedPos; |
| 2410 return pDict; | 2389 return pDict.release(); |
| 2411 } | 2390 } |
| 2391 |
| 2392 return ReadStream(pDict.release(), pContext, objnum, gennum); |
| 2412 } | 2393 } |
| 2413 if (word == FX_BSTRC(">>")) { | 2394 if (word == FX_BSTRC(">>")) { |
| 2414 m_Pos = SavedPos; | 2395 m_Pos = SavedPos; |
| 2415 return NULL; | 2396 return nullptr; |
| 2416 } | 2397 } |
| 2417 if (bTypeOnly) { | 2398 if (bTypeOnly) |
| 2418 return (CPDF_Object*)PDFOBJ_INVALID; | 2399 return (CPDF_Object*)PDFOBJ_INVALID; |
| 2419 } | 2400 |
| 2420 return NULL; | 2401 return nullptr; |
| 2421 } | 2402 } |
| 2403 |
| 2422 unsigned int CPDF_SyntaxParser::ReadEOLMarkers(FX_FILESIZE pos) { | 2404 unsigned int CPDF_SyntaxParser::ReadEOLMarkers(FX_FILESIZE pos) { |
| 2423 unsigned char byte1 = 0; | 2405 unsigned char byte1 = 0; |
| 2424 unsigned char byte2 = 0; | 2406 unsigned char byte2 = 0; |
| 2425 GetCharAt(pos, byte1); | 2407 GetCharAt(pos, byte1); |
| 2426 GetCharAt(pos + 1, byte2); | 2408 GetCharAt(pos + 1, byte2); |
| 2427 unsigned int markers = 0; | 2409 unsigned int markers = 0; |
| 2428 if (byte1 == '\r' && byte2 == '\n') { | 2410 if (byte1 == '\r' && byte2 == '\n') { |
| 2429 markers = 2; | 2411 markers = 2; |
| 2430 } else if (byte1 == '\r' || byte1 == '\n') { | 2412 } else if (byte1 == '\r' || byte1 == '\n') { |
| 2431 markers = 1; | 2413 markers = 1; |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2675 offset = byte == tag_data[taglen - 1] ? taglen - 2 : taglen - 1; | 2657 offset = byte == tag_data[taglen - 1] ? taglen - 2 : taglen - 1; |
| 2676 pos--; | 2658 pos--; |
| 2677 } | 2659 } |
| 2678 if (pos < 0) { | 2660 if (pos < 0) { |
| 2679 return FALSE; | 2661 return FALSE; |
| 2680 } | 2662 } |
| 2681 } | 2663 } |
| 2682 return FALSE; | 2664 return FALSE; |
| 2683 } | 2665 } |
| 2684 | 2666 |
| 2685 struct _SearchTagRecord { | |
| 2686 const uint8_t* m_pTag; | |
| 2687 FX_DWORD m_Len; | |
| 2688 FX_DWORD m_Offset; | |
| 2689 }; | |
| 2690 | |
| 2691 int32_t CPDF_SyntaxParser::SearchMultiWord(const CFX_ByteStringC& tags, | 2667 int32_t CPDF_SyntaxParser::SearchMultiWord(const CFX_ByteStringC& tags, |
| 2692 FX_BOOL bWholeWord, | 2668 FX_BOOL bWholeWord, |
| 2693 FX_FILESIZE limit) { | 2669 FX_FILESIZE limit) { |
| 2694 int32_t ntags = 1; | 2670 int32_t ntags = 1; |
| 2695 for (int i = 0; i < tags.GetLength(); ++i) { | 2671 for (int i = 0; i < tags.GetLength(); ++i) { |
| 2696 if (tags[i] == 0) { | 2672 if (tags[i] == 0) { |
| 2697 ++ntags; | 2673 ++ntags; |
| 2698 } | 2674 } |
| 2699 } | 2675 } |
| 2700 | 2676 |
| 2701 std::vector<_SearchTagRecord> patterns(ntags); | 2677 std::vector<SearchTagRecord> patterns(ntags); |
| 2702 FX_DWORD start = 0; | 2678 FX_DWORD start = 0; |
| 2703 FX_DWORD itag = 0; | 2679 FX_DWORD itag = 0; |
| 2704 FX_DWORD max_len = 0; | 2680 FX_DWORD max_len = 0; |
| 2705 for (int i = 0; i <= tags.GetLength(); ++i) { | 2681 for (int i = 0; i <= tags.GetLength(); ++i) { |
| 2706 if (tags[i] == 0) { | 2682 if (tags[i] == 0) { |
| 2707 FX_DWORD len = i - start; | 2683 FX_DWORD len = i - start; |
| 2708 max_len = std::max(len, max_len); | 2684 max_len = std::max(len, max_len); |
| 2709 patterns[itag].m_pTag = tags.GetPtr() + start; | 2685 patterns[itag].m_pTag = tags.GetPtr() + start; |
| 2710 patterns[itag].m_Len = len; | 2686 patterns[itag].m_Len = len; |
| 2711 patterns[itag].m_Offset = 0; | 2687 patterns[itag].m_Offset = 0; |
| 2712 start = i + 1; | 2688 start = i + 1; |
| 2713 ++itag; | 2689 ++itag; |
| 2714 } | 2690 } |
| 2715 } | 2691 } |
| 2716 | 2692 |
| 2717 const FX_FILESIZE pos_limit = m_Pos + limit; | 2693 const FX_FILESIZE pos_limit = m_Pos + limit; |
| 2718 for (FX_FILESIZE pos = m_Pos; !limit || pos < pos_limit; ++pos) { | 2694 for (FX_FILESIZE pos = m_Pos; !limit || pos < pos_limit; ++pos) { |
| 2719 uint8_t byte; | 2695 uint8_t byte; |
| 2720 if (!GetCharAt(pos, byte)) | 2696 if (!GetCharAt(pos, byte)) |
| 2721 break; | 2697 break; |
| 2722 | 2698 |
| 2723 for (int i = 0; i < ntags; ++i) { | 2699 for (int i = 0; i < ntags; ++i) { |
| 2724 _SearchTagRecord& pat = patterns[i]; | 2700 SearchTagRecord& pat = patterns[i]; |
| 2725 if (pat.m_pTag[pat.m_Offset] != byte) { | 2701 if (pat.m_pTag[pat.m_Offset] != byte) { |
| 2726 pat.m_Offset = (pat.m_pTag[0] == byte) ? 1 : 0; | 2702 pat.m_Offset = (pat.m_pTag[0] == byte) ? 1 : 0; |
| 2727 continue; | 2703 continue; |
| 2728 } | 2704 } |
| 2729 | 2705 |
| 2730 ++pat.m_Offset; | 2706 ++pat.m_Offset; |
| 2731 if (pat.m_Offset != pat.m_Len) | 2707 if (pat.m_Offset != pat.m_Len) |
| 2732 continue; | 2708 continue; |
| 2733 | 2709 |
| 2734 if (!bWholeWord || | 2710 if (!bWholeWord || |
| (...skipping 998 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3733 return PDF_UNKNOW_LINEARIZED; | 3709 return PDF_UNKNOW_LINEARIZED; |
| 3734 } | 3710 } |
| 3735 uint8_t buffer[1024]; | 3711 uint8_t buffer[1024]; |
| 3736 m_pFileRead->ReadBlock(buffer, 0, req_size); | 3712 m_pFileRead->ReadBlock(buffer, 0, req_size); |
| 3737 if (IsLinearizedFile(buffer, req_size)) { | 3713 if (IsLinearizedFile(buffer, req_size)) { |
| 3738 return PDF_IS_LINEARIZED; | 3714 return PDF_IS_LINEARIZED; |
| 3739 } | 3715 } |
| 3740 return PDF_NOT_LINEARIZED; | 3716 return PDF_NOT_LINEARIZED; |
| 3741 } | 3717 } |
| 3742 FX_BOOL CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen) { | 3718 FX_BOOL CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen) { |
| 3743 CFX_SmartPointer<IFX_FileStream> file( | 3719 ScopedFileStream file(FX_CreateMemoryStream(pData, (size_t)dwLen, FALSE)); |
| 3744 FX_CreateMemoryStream(pData, (size_t)dwLen, FALSE)); | 3720 int32_t offset = GetHeaderOffset(file.get()); |
| 3745 int32_t offset = GetHeaderOffset(file.Get()); | |
| 3746 if (offset == -1) { | 3721 if (offset == -1) { |
| 3747 m_docStatus = PDF_DATAAVAIL_ERROR; | 3722 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 3748 return FALSE; | 3723 return FALSE; |
| 3749 } | 3724 } |
| 3750 m_dwHeaderOffset = offset; | 3725 m_dwHeaderOffset = offset; |
| 3751 m_syntaxParser.InitParser(file.Get(), offset); | 3726 m_syntaxParser.InitParser(file.get(), offset); |
| 3752 m_syntaxParser.RestorePos(m_syntaxParser.m_HeaderOffset + 9); | 3727 m_syntaxParser.RestorePos(m_syntaxParser.m_HeaderOffset + 9); |
| 3753 FX_BOOL bNumber = FALSE; | 3728 FX_BOOL bNumber = FALSE; |
| 3754 CFX_ByteString wordObjNum = m_syntaxParser.GetNextWord(bNumber); | 3729 CFX_ByteString wordObjNum = m_syntaxParser.GetNextWord(bNumber); |
| 3755 if (!bNumber) { | 3730 if (!bNumber) { |
| 3756 return FALSE; | 3731 return FALSE; |
| 3757 } | 3732 } |
| 3758 FX_DWORD objnum = FXSYS_atoi(wordObjNum); | 3733 FX_DWORD objnum = FXSYS_atoi(wordObjNum); |
| 3759 if (m_pLinearized) { | 3734 if (m_pLinearized) { |
| 3760 m_pLinearized->Release(); | 3735 m_pLinearized->Release(); |
| 3761 m_pLinearized = NULL; | 3736 m_pLinearized = NULL; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 3782 return TRUE; | 3757 return TRUE; |
| 3783 } | 3758 } |
| 3784 return FALSE; | 3759 return FALSE; |
| 3785 } | 3760 } |
| 3786 FX_BOOL CPDF_DataAvail::CheckEnd(IFX_DownloadHints* pHints) { | 3761 FX_BOOL CPDF_DataAvail::CheckEnd(IFX_DownloadHints* pHints) { |
| 3787 FX_DWORD req_pos = (FX_DWORD)(m_dwFileLen > 1024 ? m_dwFileLen - 1024 : 0); | 3762 FX_DWORD req_pos = (FX_DWORD)(m_dwFileLen > 1024 ? m_dwFileLen - 1024 : 0); |
| 3788 FX_DWORD dwSize = (FX_DWORD)(m_dwFileLen - req_pos); | 3763 FX_DWORD dwSize = (FX_DWORD)(m_dwFileLen - req_pos); |
| 3789 if (m_pFileAvail->IsDataAvail(req_pos, dwSize)) { | 3764 if (m_pFileAvail->IsDataAvail(req_pos, dwSize)) { |
| 3790 uint8_t buffer[1024]; | 3765 uint8_t buffer[1024]; |
| 3791 m_pFileRead->ReadBlock(buffer, req_pos, dwSize); | 3766 m_pFileRead->ReadBlock(buffer, req_pos, dwSize); |
| 3792 CFX_SmartPointer<IFX_FileStream> file( | 3767 ScopedFileStream file(FX_CreateMemoryStream(buffer, (size_t)dwSize, FALSE)); |
| 3793 FX_CreateMemoryStream(buffer, (size_t)dwSize, FALSE)); | 3768 m_syntaxParser.InitParser(file.get(), 0); |
| 3794 m_syntaxParser.InitParser(file.Get(), 0); | |
| 3795 m_syntaxParser.RestorePos(dwSize - 1); | 3769 m_syntaxParser.RestorePos(dwSize - 1); |
| 3796 if (m_syntaxParser.SearchWord(FX_BSTRC("startxref"), TRUE, FALSE, dwSize)) { | 3770 if (m_syntaxParser.SearchWord(FX_BSTRC("startxref"), TRUE, FALSE, dwSize)) { |
| 3797 FX_BOOL bNumber; | 3771 FX_BOOL bNumber; |
| 3798 m_syntaxParser.GetNextWord(bNumber); | 3772 m_syntaxParser.GetNextWord(bNumber); |
| 3799 CFX_ByteString xrefpos_str = m_syntaxParser.GetNextWord(bNumber); | 3773 CFX_ByteString xrefpos_str = m_syntaxParser.GetNextWord(bNumber); |
| 3800 if (!bNumber) { | 3774 if (!bNumber) { |
| 3801 m_docStatus = PDF_DATAAVAIL_ERROR; | 3775 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 3802 return FALSE; | 3776 return FALSE; |
| 3803 } | 3777 } |
| 3804 m_dwXRefOffset = (FX_FILESIZE)FXSYS_atoi64(xrefpos_str); | 3778 m_dwXRefOffset = (FX_FILESIZE)FXSYS_atoi64(xrefpos_str); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3820 int32_t CPDF_DataAvail::CheckCrossRefStream(IFX_DownloadHints* pHints, | 3794 int32_t CPDF_DataAvail::CheckCrossRefStream(IFX_DownloadHints* pHints, |
| 3821 FX_FILESIZE& xref_offset) { | 3795 FX_FILESIZE& xref_offset) { |
| 3822 xref_offset = 0; | 3796 xref_offset = 0; |
| 3823 FX_DWORD req_size = | 3797 FX_DWORD req_size = |
| 3824 (FX_DWORD)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512); | 3798 (FX_DWORD)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512); |
| 3825 if (m_pFileAvail->IsDataAvail(m_Pos, req_size)) { | 3799 if (m_pFileAvail->IsDataAvail(m_Pos, req_size)) { |
| 3826 int32_t iSize = (int32_t)(m_Pos + req_size - m_dwCurrentXRefSteam); | 3800 int32_t iSize = (int32_t)(m_Pos + req_size - m_dwCurrentXRefSteam); |
| 3827 CFX_BinaryBuf buf(iSize); | 3801 CFX_BinaryBuf buf(iSize); |
| 3828 uint8_t* pBuf = buf.GetBuffer(); | 3802 uint8_t* pBuf = buf.GetBuffer(); |
| 3829 m_pFileRead->ReadBlock(pBuf, m_dwCurrentXRefSteam, iSize); | 3803 m_pFileRead->ReadBlock(pBuf, m_dwCurrentXRefSteam, iSize); |
| 3830 CFX_SmartPointer<IFX_FileStream> file( | 3804 ScopedFileStream file(FX_CreateMemoryStream(pBuf, (size_t)iSize, FALSE)); |
| 3831 FX_CreateMemoryStream(pBuf, (size_t)iSize, FALSE)); | 3805 m_parser.m_Syntax.InitParser(file.get(), 0); |
| 3832 m_parser.m_Syntax.InitParser(file.Get(), 0); | |
| 3833 FX_BOOL bNumber = FALSE; | 3806 FX_BOOL bNumber = FALSE; |
| 3834 CFX_ByteString objnum = m_parser.m_Syntax.GetNextWord(bNumber); | 3807 CFX_ByteString objnum = m_parser.m_Syntax.GetNextWord(bNumber); |
| 3835 if (!bNumber) { | 3808 if (!bNumber) { |
| 3836 return -1; | 3809 return -1; |
| 3837 } | 3810 } |
| 3838 FX_DWORD objNum = FXSYS_atoi(objnum); | 3811 FX_DWORD objNum = FXSYS_atoi(objnum); |
| 3839 CPDF_Object* pObj = m_parser.ParseIndirectObjectAt(NULL, 0, objNum, NULL); | 3812 CPDF_Object* pObj = m_parser.ParseIndirectObjectAt(NULL, 0, objNum, NULL); |
| 3840 if (!pObj) { | 3813 if (!pObj) { |
| 3841 m_Pos += m_parser.m_Syntax.SavePos(); | 3814 m_Pos += m_parser.m_Syntax.SavePos(); |
| 3842 return 0; | 3815 return 0; |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4060 int32_t iSize = (int32_t)(m_Pos + iTrailerSize - m_dwTrailerOffset); | 4033 int32_t iSize = (int32_t)(m_Pos + iTrailerSize - m_dwTrailerOffset); |
| 4061 CFX_BinaryBuf buf(iSize); | 4034 CFX_BinaryBuf buf(iSize); |
| 4062 uint8_t* pBuf = buf.GetBuffer(); | 4035 uint8_t* pBuf = buf.GetBuffer(); |
| 4063 if (!pBuf) { | 4036 if (!pBuf) { |
| 4064 m_docStatus = PDF_DATAAVAIL_ERROR; | 4037 m_docStatus = PDF_DATAAVAIL_ERROR; |
| 4065 return FALSE; | 4038 return FALSE; |
| 4066 } | 4039 } |
| 4067 if (!m_pFileRead->ReadBlock(pBuf, m_dwTrailerOffset, iSize)) { | 4040 if (!m_pFileRead->ReadBlock(pBuf, m_dwTrailerOffset, iSize)) { |
| 4068 return FALSE; | 4041 return FALSE; |
| 4069 } | 4042 } |
| 4070 CFX_SmartPointer<IFX_FileStream> file( | 4043 ScopedFileStream file(FX_CreateMemoryStream(pBuf, (size_t)iSize, FALSE)); |
| 4071 FX_CreateMemoryStream(pBuf, (size_t)iSize, FALSE)); | 4044 m_syntaxParser.InitParser(file.get(), 0); |
| 4072 m_syntaxParser.InitParser(file.Get(), 0); | 4045 nonstd::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>> pTrailer( |
| 4073 CPDF_Object* pTrailer = m_syntaxParser.GetObject(nullptr, 0, 0); | 4046 m_syntaxParser.GetObject(nullptr, 0, 0)); |
| 4074 if (!pTrailer) { | 4047 if (!pTrailer) { |
| 4075 m_Pos += m_syntaxParser.SavePos(); | 4048 m_Pos += m_syntaxParser.SavePos(); |
| 4076 pHints->AddSegment(m_Pos, iTrailerSize); | 4049 pHints->AddSegment(m_Pos, iTrailerSize); |
| 4077 return FALSE; | 4050 return FALSE; |
| 4078 } | 4051 } |
| 4079 if (pTrailer->GetType() != PDFOBJ_DICTIONARY) { | 4052 if (pTrailer->GetType() != PDFOBJ_DICTIONARY) |
| 4080 pTrailer->Release(); | |
| 4081 return FALSE; | 4053 return FALSE; |
| 4082 } | 4054 |
| 4083 CPDF_Dictionary* pTrailerDict = pTrailer->GetDict(); | 4055 CPDF_Dictionary* pTrailerDict = pTrailer->GetDict(); |
| 4084 CPDF_Object* pEncrypt = pTrailerDict->GetElement("Encrypt"); | 4056 CPDF_Object* pEncrypt = pTrailerDict->GetElement("Encrypt"); |
| 4085 if (pEncrypt && pEncrypt->GetType() == PDFOBJ_REFERENCE) { | 4057 if (pEncrypt && pEncrypt->GetType() == PDFOBJ_REFERENCE) { |
| 4086 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; | 4058 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; |
| 4087 pTrailer->Release(); | |
| 4088 return TRUE; | 4059 return TRUE; |
| 4089 } | 4060 } |
| 4090 FX_DWORD xrefpos = GetDirectInteger(pTrailer->GetDict(), FX_BSTRC("Prev")); | 4061 |
| 4062 FX_DWORD xrefpos = GetDirectInteger(pTrailerDict, FX_BSTRC("Prev")); |
| 4091 if (xrefpos) { | 4063 if (xrefpos) { |
| 4092 m_dwPrevXRefOffset = | 4064 m_dwPrevXRefOffset = GetDirectInteger(pTrailerDict, FX_BSTRC("XRefStm")); |
| 4093 GetDirectInteger(pTrailer->GetDict(), FX_BSTRC("XRefStm")); | |
| 4094 pTrailer->Release(); | |
| 4095 if (m_dwPrevXRefOffset) { | 4065 if (m_dwPrevXRefOffset) { |
| 4096 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; | 4066 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; |
| 4097 } else { | 4067 } else { |
| 4098 m_dwPrevXRefOffset = xrefpos; | 4068 m_dwPrevXRefOffset = xrefpos; |
| 4099 if (m_dwPrevXRefOffset >= m_dwFileLen) { | 4069 if (m_dwPrevXRefOffset >= m_dwFileLen) { |
| 4100 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; | 4070 m_docStatus = PDF_DATAAVAIL_LOADALLFILE; |
| 4101 } else { | 4071 } else { |
| 4102 SetStartOffset(m_dwPrevXRefOffset); | 4072 SetStartOffset(m_dwPrevXRefOffset); |
| 4103 m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND; | 4073 m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND; |
| 4104 } | 4074 } |
| 4105 } | 4075 } |
| 4106 return TRUE; | 4076 return TRUE; |
| 4107 } | 4077 } |
| 4108 m_dwPrevXRefOffset = 0; | 4078 m_dwPrevXRefOffset = 0; |
| 4109 m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND; | 4079 m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND; |
| 4110 pTrailer->Release(); | |
| 4111 return TRUE; | 4080 return TRUE; |
| 4112 } | 4081 } |
| 4113 pHints->AddSegment(m_Pos, iTrailerSize); | 4082 pHints->AddSegment(m_Pos, iTrailerSize); |
| 4114 return FALSE; | 4083 return FALSE; |
| 4115 } | 4084 } |
| 4116 | 4085 |
| 4117 FX_BOOL CPDF_DataAvail::CheckPage(int32_t iPage, IFX_DownloadHints* pHints) { | 4086 FX_BOOL CPDF_DataAvail::CheckPage(int32_t iPage, IFX_DownloadHints* pHints) { |
| 4118 while (TRUE) { | 4087 while (TRUE) { |
| 4119 switch (m_docStatus) { | 4088 switch (m_docStatus) { |
| 4120 case PDF_DATAAVAIL_PAGETREE: | 4089 case PDF_DATAAVAIL_PAGETREE: |
| (...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4654 return FALSE; | 4623 return FALSE; |
| 4655 } | 4624 } |
| 4656 CPDF_PageNode::~CPDF_PageNode() { | 4625 CPDF_PageNode::~CPDF_PageNode() { |
| 4657 int32_t iSize = m_childNode.GetSize(); | 4626 int32_t iSize = m_childNode.GetSize(); |
| 4658 for (int32_t i = 0; i < iSize; ++i) { | 4627 for (int32_t i = 0; i < iSize; ++i) { |
| 4659 CPDF_PageNode* pNode = (CPDF_PageNode*)m_childNode[i]; | 4628 CPDF_PageNode* pNode = (CPDF_PageNode*)m_childNode[i]; |
| 4660 delete pNode; | 4629 delete pNode; |
| 4661 } | 4630 } |
| 4662 m_childNode.RemoveAll(); | 4631 m_childNode.RemoveAll(); |
| 4663 } | 4632 } |
| OLD | NEW |