1e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Copyright 2015 PDFium Authors. All rights reserved. 2e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Use of this source code is governed by a BSD-style license that can be 3e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// found in the LICENSE file. 4e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 5ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#include "core/include/fxcrt/fx_string.h" 6ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#include "public/fpdf_doc.h" 7ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#include "public/fpdfview.h" 8ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#include "testing/embedder_test.h" 9ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#include "testing/fx_string_testhelpers.h" 10ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#include "testing/test_support.h" 11e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include "testing/gtest/include/gtest/gtest.h" 12e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 13ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannclass FPDFDocEmbeddertest : public EmbedderTest {}; 14e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 15e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovTEST_F(FPDFDocEmbeddertest, DestGetPageIndex) { 16ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_TRUE(OpenDocument("named_dests.pdf")); 17e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 18e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // NULL FPDF_DEST case. 19ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_EQ(0U, FPDFDest_GetPageIndex(document(), nullptr)); 20e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 21e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Page number directly in item from Dests NameTree. 22e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FPDF_DEST dest = FPDF_GetNamedDestByName(document(), "First"); 23e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov EXPECT_NE(nullptr, dest); 24ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_EQ(1U, FPDFDest_GetPageIndex(document(), dest)); 25e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 26e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Page number via object reference in item from Dests NameTree. 27e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov dest = FPDF_GetNamedDestByName(document(), "Next"); 28e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov EXPECT_NE(nullptr, dest); 29ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_EQ(1U, FPDFDest_GetPageIndex(document(), dest)); 30e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 31e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Page number directly in item from Dests dictionary. 32e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov dest = FPDF_GetNamedDestByName(document(), "FirstAlternate"); 33e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov EXPECT_NE(nullptr, dest); 34ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_EQ(11U, FPDFDest_GetPageIndex(document(), dest)); 35e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 36e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Invalid object reference in item from Dests NameTree. 37e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov dest = FPDF_GetNamedDestByName(document(), "LastAlternate"); 38e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov EXPECT_NE(nullptr, dest); 39ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_EQ(0U, FPDFDest_GetPageIndex(document(), dest)); 40ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 41ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 42ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannTEST_F(FPDFDocEmbeddertest, ActionGetFilePath) { 43ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_TRUE(OpenDocument("launch_action.pdf")); 44ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 45ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FPDF_PAGE page = FPDF_LoadPage(document(), 0); 46ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ASSERT_TRUE(page); 47ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 48ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann // The target action is nearly the size of the whole page. 49ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FPDF_LINK link = FPDFLink_GetLinkAtPoint(page, 100, 100); 50ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ASSERT_TRUE(link); 51ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 52ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FPDF_ACTION action = FPDFLink_GetAction(link); 53ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ASSERT_TRUE(action); 54ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 55ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const char kExpectedResult[] = "test.pdf"; 56ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const unsigned long kExpectedLength = sizeof(kExpectedResult); 57ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann unsigned long bufsize = FPDFAction_GetFilePath(action, nullptr, 0); 58ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ASSERT_EQ(kExpectedLength, bufsize); 59ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 60ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann char buf[kExpectedLength]; 61ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_EQ(bufsize, FPDFAction_GetFilePath(action, buf, bufsize)); 62ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_EQ(std::string(kExpectedResult), std::string(buf)); 63ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 64ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FPDF_ClosePage(page); 65ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 66ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 67ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannTEST_F(FPDFDocEmbeddertest, NoBookmarks) { 68ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann // Open a file with no bookmarks. 69ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_TRUE(OpenDocument("named_dests.pdf")); 70ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 71ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann // The non-existent top-level bookmark has no title. 72ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann unsigned short buf[128]; 73ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_EQ(0, FPDFBookmark_GetTitle(nullptr, buf, sizeof(buf))); 74ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 75ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann // The non-existent top-level bookmark has no children. 76ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_EQ(nullptr, FPDFBookmark_GetFirstChild(document(), nullptr)); 77ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 78ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 79ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannTEST_F(FPDFDocEmbeddertest, Bookmarks) { 80ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann // Open a file with two bookmarks. 81ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_TRUE(OpenDocument("bookmarks.pdf")); 82ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 83ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann // The existent top-level bookmark has no title. 84ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann unsigned short buf[128]; 85ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_EQ(0, FPDFBookmark_GetTitle(nullptr, buf, sizeof(buf))); 86ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 87ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FPDF_BOOKMARK child = FPDFBookmark_GetFirstChild(document(), nullptr); 88ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_NE(nullptr, child); 89ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_EQ(34, FPDFBookmark_GetTitle(child, buf, sizeof(buf))); 90ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_EQ(CFX_WideString(L"A Good Beginning"), 91ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CFX_WideString::FromUTF16LE(buf, 16)); 92ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 93ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_EQ(nullptr, FPDFBookmark_GetFirstChild(document(), child)); 94ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 95ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FPDF_BOOKMARK sibling = FPDFBookmark_GetNextSibling(document(), child); 96ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_NE(nullptr, sibling); 97ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_EQ(28, FPDFBookmark_GetTitle(sibling, buf, sizeof(buf))); 98ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_EQ(CFX_WideString(L"A Good Ending"), 99ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CFX_WideString::FromUTF16LE(buf, 13)); 100ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 101ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_EQ(nullptr, FPDFBookmark_GetNextSibling(document(), sibling)); 102ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 103ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 104ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannTEST_F(FPDFDocEmbeddertest, FindBookmarks) { 105ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann // Open a file with two bookmarks. 106ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_TRUE(OpenDocument("bookmarks.pdf")); 107ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 108ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann // Find the first one, based on its known title. 109ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann std::unique_ptr<unsigned short, pdfium::FreeDeleter> title = 110ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann GetFPDFWideString(L"A Good Beginning"); 111ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FPDF_BOOKMARK child = FPDFBookmark_Find(document(), title.get()); 112ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_NE(nullptr, child); 113ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 114ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann // Check that the string matches. 115ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann unsigned short buf[128]; 116ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_EQ(34, FPDFBookmark_GetTitle(child, buf, sizeof(buf))); 117ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_EQ(CFX_WideString(L"A Good Beginning"), 118ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CFX_WideString::FromUTF16LE(buf, 16)); 119ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 120ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann // Check that it is them same as the one returned by GetFirstChild. 121ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_EQ(child, FPDFBookmark_GetFirstChild(document(), nullptr)); 122ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 123ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann // Try to find one using a non-existent title. 124ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann std::unique_ptr<unsigned short, pdfium::FreeDeleter> bad_title = 125ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann GetFPDFWideString(L"A BAD Beginning"); 126ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann EXPECT_EQ(nullptr, FPDFBookmark_Find(document(), bad_title.get())); 127e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 128