Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(414)

Side by Side Diff: core/fpdfapi/parser/cpdf_document.cpp

Issue 2636403003: Bad indexing in CPDF_Document::FindPageIndex when page tree corrupt. (Closed)
Patch Set: return -1 for out-of-range Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « core/fpdfapi/parser/cpdf_document.h ('k') | fpdfsdk/fpdfdoc_embeddertest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "core/fpdfapi/parser/cpdf_document.h" 7 #include "core/fpdfapi/parser/cpdf_document.h"
8 8
9 #include <memory> 9 #include <memory>
10 #include <set> 10 #include <set>
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 CPDF_Dictionary* pPage = TraversePDFPages(iPage, &nPagesToGo, 0); 509 CPDF_Dictionary* pPage = TraversePDFPages(iPage, &nPagesToGo, 0);
510 m_iNextPageToTraverse = iPage + 1; 510 m_iNextPageToTraverse = iPage + 1;
511 return pPage; 511 return pPage;
512 } 512 }
513 513
514 void CPDF_Document::SetPageObjNum(int iPage, uint32_t objNum) { 514 void CPDF_Document::SetPageObjNum(int iPage, uint32_t objNum) {
515 m_PageList[iPage] = objNum; 515 m_PageList[iPage] = objNum;
516 } 516 }
517 517
518 int CPDF_Document::FindPageIndex(CPDF_Dictionary* pNode, 518 int CPDF_Document::FindPageIndex(CPDF_Dictionary* pNode,
519 uint32_t& skip_count, 519 uint32_t* skip_count,
520 uint32_t objnum, 520 uint32_t objnum,
521 int& index, 521 int* index,
522 int level) { 522 int level) {
523 if (!pNode->KeyExist("Kids")) { 523 if (!pNode->KeyExist("Kids")) {
524 if (objnum == pNode->GetObjNum()) 524 if (objnum == pNode->GetObjNum())
525 return index; 525 return *index;
526 526
527 if (skip_count) 527 if (*skip_count)
528 skip_count--; 528 (*skip_count)--;
529 529
530 index++; 530 (*index)++;
531 return -1; 531 return -1;
532 } 532 }
533 533
534 CPDF_Array* pKidList = pNode->GetArrayFor("Kids"); 534 CPDF_Array* pKidList = pNode->GetArrayFor("Kids");
535 if (!pKidList) 535 if (!pKidList)
536 return -1; 536 return -1;
537 537
538 if (level >= FX_MAX_PAGE_LEVEL) 538 if (level >= FX_MAX_PAGE_LEVEL)
539 return -1; 539 return -1;
540 540
541 size_t count = pNode->GetIntegerFor("Count"); 541 size_t count = pNode->GetIntegerFor("Count");
542 if (count <= skip_count) { 542 if (count <= *skip_count) {
543 skip_count -= count; 543 (*skip_count) -= count;
544 index += count; 544 (*index) += count;
545 return -1; 545 return -1;
546 } 546 }
547 547
548 if (count && count == pKidList->GetCount()) { 548 if (count && count == pKidList->GetCount()) {
549 for (size_t i = 0; i < count; i++) { 549 for (size_t i = 0; i < count; i++) {
550 if (CPDF_Reference* pKid = ToReference(pKidList->GetObjectAt(i))) { 550 CPDF_Reference* pKid = ToReference(pKidList->GetObjectAt(i));
551 if (pKid->GetRefObjNum() == objnum) { 551 if (pKid && pKid->GetRefObjNum() == objnum)
552 m_PageList[index + i] = objnum; 552 return static_cast<int>(*index + i);
Tom Sepez 2017/01/18 18:08:42 Note: move to 592 and sanity checked.
553 return static_cast<int>(index + i);
554 }
555 }
556 } 553 }
557 } 554 }
558 555
559 for (size_t i = 0; i < pKidList->GetCount(); i++) { 556 for (size_t i = 0; i < pKidList->GetCount(); i++) {
560 CPDF_Dictionary* pKid = pKidList->GetDictAt(i); 557 CPDF_Dictionary* pKid = pKidList->GetDictAt(i);
561 if (!pKid || pKid == pNode) 558 if (!pKid || pKid == pNode)
562 continue; 559 continue;
563 560
564 int found_index = FindPageIndex(pKid, skip_count, objnum, index, level + 1); 561 int found_index = FindPageIndex(pKid, skip_count, objnum, index, level + 1);
565 if (found_index >= 0) 562 if (found_index >= 0)
(...skipping 12 matching lines...) Expand all
578 575
579 if (!bSkipped && m_PageList[i] == 0) { 576 if (!bSkipped && m_PageList[i] == 0) {
580 skip_count = i; 577 skip_count = i;
581 bSkipped = true; 578 bSkipped = true;
582 } 579 }
583 } 580 }
584 CPDF_Dictionary* pPages = GetPagesDict(); 581 CPDF_Dictionary* pPages = GetPagesDict();
585 if (!pPages) 582 if (!pPages)
586 return -1; 583 return -1;
587 584
588 int index = 0; 585 int start_index = 0;
589 return FindPageIndex(pPages, skip_count, objnum, index); 586 int found_index = FindPageIndex(pPages, &skip_count, objnum, &start_index);
587
588 // Corrupt page tree may yield out-of-range results.
589 if (found_index < 0 || found_index >= pdfium::CollectionSize<int>(m_PageList))
590 return -1;
591
592 m_PageList[found_index] = objnum;
593 return found_index;
590 } 594 }
591 595
592 int CPDF_Document::GetPageCount() const { 596 int CPDF_Document::GetPageCount() const {
593 return pdfium::CollectionSize<int>(m_PageList); 597 return pdfium::CollectionSize<int>(m_PageList);
594 } 598 }
595 599
596 int CPDF_Document::RetrievePageCount() const { 600 int CPDF_Document::RetrievePageCount() const {
597 CPDF_Dictionary* pPages = GetPagesDict(); 601 CPDF_Dictionary* pPages = GetPagesDict();
598 if (!pPages) 602 if (!pPages)
599 return 0; 603 return 0;
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
1041 pFontDesc->SetNewFor<CPDF_Number>("CapHeight", capheight); 1045 pFontDesc->SetNewFor<CPDF_Number>("CapHeight", capheight);
1042 pFontDict->SetNewFor<CPDF_Reference>( 1046 pFontDict->SetNewFor<CPDF_Reference>(
1043 "FontDescriptor", this, 1047 "FontDescriptor", this,
1044 AddIndirectObject(std::move(pFontDesc))->GetObjNum()); 1048 AddIndirectObject(std::move(pFontDesc))->GetObjNum());
1045 hFont = SelectObject(hDC, hFont); 1049 hFont = SelectObject(hDC, hFont);
1046 DeleteObject(hFont); 1050 DeleteObject(hFont);
1047 DeleteDC(hDC); 1051 DeleteDC(hDC);
1048 return LoadFont(pBaseDict); 1052 return LoadFont(pBaseDict);
1049 } 1053 }
1050 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 1054 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
OLDNEW
« no previous file with comments | « core/fpdfapi/parser/cpdf_document.h ('k') | fpdfsdk/fpdfdoc_embeddertest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698