| 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 "public/fpdf_doc.h" | 7 #include "public/fpdf_doc.h" |
| 8 | 8 |
| 9 #include <set> |
| 10 |
| 9 #include "fpdfsdk/include/fsdk_define.h" | 11 #include "fpdfsdk/include/fsdk_define.h" |
| 12 #include "third_party/base/stl_util.h" |
| 10 | 13 |
| 11 namespace { | 14 namespace { |
| 12 | 15 |
| 13 int THISMODULE = 0; | 16 int THISMODULE = 0; |
| 14 | 17 |
| 15 CPDF_Bookmark FindBookmark(const CPDF_BookmarkTree& tree, | 18 CPDF_Bookmark FindBookmark(const CPDF_BookmarkTree& tree, |
| 16 CPDF_Bookmark bookmark, | 19 CPDF_Bookmark bookmark, |
| 17 const CFX_WideString& title) { | 20 const CFX_WideString& title, |
| 21 std::set<CPDF_Dictionary*>* visited) { |
| 22 // Return if already checked to avoid circular calling. |
| 23 if (pdfium::ContainsKey(*visited, bookmark.GetDict())) |
| 24 return CPDF_Bookmark(); |
| 25 visited->insert(bookmark.GetDict()); |
| 26 |
| 18 if (bookmark.GetDict() && | 27 if (bookmark.GetDict() && |
| 19 bookmark.GetTitle().CompareNoCase(title.c_str()) == 0) { | 28 bookmark.GetTitle().CompareNoCase(title.c_str()) == 0) { |
| 20 // First check this item | 29 // First check this item. |
| 21 return bookmark; | 30 return bookmark; |
| 22 } | 31 } |
| 23 // go into children items | 32 |
| 33 // Go into children items. |
| 24 CPDF_Bookmark child = tree.GetFirstChild(bookmark); | 34 CPDF_Bookmark child = tree.GetFirstChild(bookmark); |
| 25 while (child.GetDict()) { | 35 while (child.GetDict() && !pdfium::ContainsKey(*visited, child.GetDict())) { |
| 26 // check if this item | 36 // Check this item and its children. |
| 27 CPDF_Bookmark found = FindBookmark(tree, child, title); | 37 CPDF_Bookmark found = FindBookmark(tree, child, title, visited); |
| 28 if (found.GetDict()) | 38 if (found.GetDict()) |
| 29 return found; | 39 return found; |
| 30 child = tree.GetNextSibling(child); | 40 child = tree.GetNextSibling(child); |
| 31 } | 41 } |
| 32 return CPDF_Bookmark(); | 42 return CPDF_Bookmark(); |
| 33 } | 43 } |
| 34 | 44 |
| 35 void ReleaseLinkList(void* data) { | 45 void ReleaseLinkList(void* data) { |
| 36 delete (CPDF_LinkList*)data; | 46 delete (CPDF_LinkList*)data; |
| 37 } | 47 } |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 DLLEXPORT FPDF_BOOKMARK STDCALL FPDFBookmark_Find(FPDF_DOCUMENT document, | 104 DLLEXPORT FPDF_BOOKMARK STDCALL FPDFBookmark_Find(FPDF_DOCUMENT document, |
| 95 FPDF_WIDESTRING title) { | 105 FPDF_WIDESTRING title) { |
| 96 if (!title || title[0] == 0) | 106 if (!title || title[0] == 0) |
| 97 return nullptr; | 107 return nullptr; |
| 98 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); | 108 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); |
| 99 if (!pDoc) | 109 if (!pDoc) |
| 100 return nullptr; | 110 return nullptr; |
| 101 CPDF_BookmarkTree tree(pDoc); | 111 CPDF_BookmarkTree tree(pDoc); |
| 102 FX_STRSIZE len = CFX_WideString::WStringLength(title); | 112 FX_STRSIZE len = CFX_WideString::WStringLength(title); |
| 103 CFX_WideString encodedTitle = CFX_WideString::FromUTF16LE(title, len); | 113 CFX_WideString encodedTitle = CFX_WideString::FromUTF16LE(title, len); |
| 104 return FindBookmark(tree, CPDF_Bookmark(), encodedTitle).GetDict(); | 114 std::set<CPDF_Dictionary*> visited; |
| 115 return FindBookmark(tree, CPDF_Bookmark(), encodedTitle, &visited).GetDict(); |
| 105 } | 116 } |
| 106 | 117 |
| 107 DLLEXPORT FPDF_DEST STDCALL FPDFBookmark_GetDest(FPDF_DOCUMENT document, | 118 DLLEXPORT FPDF_DEST STDCALL FPDFBookmark_GetDest(FPDF_DOCUMENT document, |
| 108 FPDF_BOOKMARK pDict) { | 119 FPDF_BOOKMARK pDict) { |
| 109 if (!pDict) | 120 if (!pDict) |
| 110 return nullptr; | 121 return nullptr; |
| 111 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); | 122 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); |
| 112 if (!pDoc) | 123 if (!pDoc) |
| 113 return nullptr; | 124 return nullptr; |
| 114 CPDF_Bookmark bookmark(ToDictionary(static_cast<CPDF_Object*>(pDict))); | 125 CPDF_Bookmark bookmark(ToDictionary(static_cast<CPDF_Object*>(pDict))); |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 347 return 0; | 358 return 0; |
| 348 CFX_WideString text = pInfo->GetUnicodeTextBy(tag); | 359 CFX_WideString text = pInfo->GetUnicodeTextBy(tag); |
| 349 // Use UTF-16LE encoding | 360 // Use UTF-16LE encoding |
| 350 CFX_ByteString encodedText = text.UTF16LE_Encode(); | 361 CFX_ByteString encodedText = text.UTF16LE_Encode(); |
| 351 unsigned long len = encodedText.GetLength(); | 362 unsigned long len = encodedText.GetLength(); |
| 352 if (buffer && buflen >= len) { | 363 if (buffer && buflen >= len) { |
| 353 FXSYS_memcpy(buffer, encodedText.c_str(), len); | 364 FXSYS_memcpy(buffer, encodedText.c_str(), len); |
| 354 } | 365 } |
| 355 return len; | 366 return len; |
| 356 } | 367 } |
| OLD | NEW |