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

Side by Side Diff: pdf/pdfium/pdfium_engine.cc

Issue 1401263005: Stack exhaustion if PDFium returns circular bookmarks. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Depth goes last. Created 5 years, 2 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium 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 #include "pdf/pdfium/pdfium_engine.h" 5 #include "pdf/pdfium/pdfium_engine.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include "base/i18n/icu_encoding_detection.h" 9 #include "base/i18n/icu_encoding_detection.h"
10 #include "base/i18n/icu_string_conversions.h" 10 #include "base/i18n/icu_string_conversions.h"
(...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 // Do nothing 537 // Do nothing
538 #else 538 #else
539 NOTIMPLEMENTED(); 539 NOTIMPLEMENTED();
540 #endif 540 #endif
541 } 541 }
542 542
543 // Returns a VarDictionary (representing a bookmark), which in turn contains 543 // Returns a VarDictionary (representing a bookmark), which in turn contains
544 // child VarDictionaries (representing the child bookmarks). 544 // child VarDictionaries (representing the child bookmarks).
545 // If NULL is passed in as the bookmark then we traverse from the "root". 545 // If NULL is passed in as the bookmark then we traverse from the "root".
546 // Note that the "root" bookmark contains no useful information. 546 // Note that the "root" bookmark contains no useful information.
547 pp::VarDictionary TraverseBookmarks(FPDF_DOCUMENT doc, FPDF_BOOKMARK bookmark) { 547 pp::VarDictionary TraverseBookmarks(FPDF_DOCUMENT doc,
548 FPDF_BOOKMARK bookmark,
549 unsigned int depth) {
548 pp::VarDictionary dict; 550 pp::VarDictionary dict;
549 base::string16 title; 551 base::string16 title;
550 unsigned long buffer_size = FPDFBookmark_GetTitle(bookmark, NULL, 0); 552 unsigned long buffer_size = FPDFBookmark_GetTitle(bookmark, NULL, 0);
551 if (buffer_size > 0) { 553 if (buffer_size > 0) {
552 PDFiumAPIStringBufferSizeInBytesAdapter<base::string16> api_string_adapter( 554 PDFiumAPIStringBufferSizeInBytesAdapter<base::string16> api_string_adapter(
553 &title, buffer_size, true); 555 &title, buffer_size, true);
554 api_string_adapter.Close(FPDFBookmark_GetTitle( 556 api_string_adapter.Close(FPDFBookmark_GetTitle(
555 bookmark, api_string_adapter.GetData(), buffer_size)); 557 bookmark, api_string_adapter.GetData(), buffer_size));
556 } 558 }
557 dict.Set(pp::Var("title"), pp::Var(base::UTF16ToUTF8(title))); 559 dict.Set(pp::Var("title"), pp::Var(base::UTF16ToUTF8(title)));
558 560
559 FPDF_DEST dest = FPDFBookmark_GetDest(doc, bookmark); 561 FPDF_DEST dest = FPDFBookmark_GetDest(doc, bookmark);
560 // Some bookmarks don't have a page to select. 562 // Some bookmarks don't have a page to select.
561 if (dest) { 563 if (dest) {
562 int page_index = FPDFDest_GetPageIndex(doc, dest); 564 int page_index = FPDFDest_GetPageIndex(doc, dest);
563 dict.Set(pp::Var("page"), pp::Var(page_index)); 565 dict.Set(pp::Var("page"), pp::Var(page_index));
564 } 566 }
565 567
566 pp::VarArray children; 568 pp::VarArray children;
567 int child_index = 0; 569
568 for (FPDF_BOOKMARK child_bookmark = FPDFBookmark_GetFirstChild(doc, bookmark); 570 // Don't trust PDFium to handle circular bookmarks.
569 child_bookmark != NULL; 571 const unsigned int kMaxDepth = 128;
570 child_bookmark = FPDFBookmark_GetNextSibling(doc, child_bookmark)) { 572 if (depth < kMaxDepth) {
571 children.Set(child_index, TraverseBookmarks(doc, child_bookmark)); 573 int child_index = 0;
572 child_index++; 574 for (FPDF_BOOKMARK child_bookmark =
575 FPDFBookmark_GetFirstChild(doc, bookmark);
576 child_bookmark != NULL;
577 child_bookmark = FPDFBookmark_GetNextSibling(doc, child_bookmark)) {
578 children.Set(child_index,
579 TraverseBookmarks(doc, child_bookmark, depth + 1));
580 child_index++;
581 }
573 } 582 }
574 dict.Set(pp::Var("children"), children); 583 dict.Set(pp::Var("children"), children);
575 return dict; 584 return dict;
576 } 585 }
577 586
578 std::string GetDocumentMetadata(FPDF_DOCUMENT doc, const std::string& key) { 587 std::string GetDocumentMetadata(FPDF_DOCUMENT doc, const std::string& key) {
579 size_t size = FPDF_GetMetaText(doc, key.c_str(), nullptr, 0); 588 size_t size = FPDF_GetMetaText(doc, key.c_str(), nullptr, 0);
580 if (size == 0) 589 if (size == 0)
581 return std::string(); 590 return std::string();
582 591
(...skipping 1843 matching lines...) Expand 10 before | Expand all | Expand 10 after
2426 selection_.push_back(PDFiumRange(pages_[i], 0, 2435 selection_.push_back(PDFiumRange(pages_[i], 0,
2427 pages_[i]->GetCharCount())); 2436 pages_[i]->GetCharCount()));
2428 } 2437 }
2429 } 2438 }
2430 2439
2431 int PDFiumEngine::GetNumberOfPages() { 2440 int PDFiumEngine::GetNumberOfPages() {
2432 return pages_.size(); 2441 return pages_.size();
2433 } 2442 }
2434 2443
2435 pp::VarArray PDFiumEngine::GetBookmarks() { 2444 pp::VarArray PDFiumEngine::GetBookmarks() {
2436 pp::VarDictionary dict = TraverseBookmarks(doc_, NULL); 2445 pp::VarDictionary dict = TraverseBookmarks(doc_, NULL, 0);
2437 // The root bookmark contains no useful information. 2446 // The root bookmark contains no useful information.
2438 return pp::VarArray(dict.Get(pp::Var("children"))); 2447 return pp::VarArray(dict.Get(pp::Var("children")));
2439 } 2448 }
2440 2449
2441 int PDFiumEngine::GetNamedDestinationPage(const std::string& destination) { 2450 int PDFiumEngine::GetNamedDestinationPage(const std::string& destination) {
2442 // Look for the destination. 2451 // Look for the destination.
2443 FPDF_DEST dest = FPDF_GetNamedDestByName(doc_, destination.c_str()); 2452 FPDF_DEST dest = FPDF_GetNamedDestByName(doc_, destination.c_str());
2444 if (!dest) { 2453 if (!dest) {
2445 // Look for a bookmark with the same name. 2454 // Look for a bookmark with the same name.
2446 base::string16 destination_wide = base::UTF8ToUTF16(destination); 2455 base::string16 destination_wide = base::UTF8ToUTF16(destination);
(...skipping 1641 matching lines...) Expand 10 before | Expand all | Expand 10 after
4088 double* height) { 4097 double* height) {
4089 FPDF_DOCUMENT doc = FPDF_LoadMemDocument(pdf_buffer, pdf_buffer_size, NULL); 4098 FPDF_DOCUMENT doc = FPDF_LoadMemDocument(pdf_buffer, pdf_buffer_size, NULL);
4090 if (!doc) 4099 if (!doc)
4091 return false; 4100 return false;
4092 bool success = FPDF_GetPageSizeByIndex(doc, page_number, width, height) != 0; 4101 bool success = FPDF_GetPageSizeByIndex(doc, page_number, width, height) != 0;
4093 FPDF_CloseDocument(doc); 4102 FPDF_CloseDocument(doc);
4094 return success; 4103 return success;
4095 } 4104 }
4096 4105
4097 } // namespace chrome_pdf 4106 } // namespace chrome_pdf
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698