Home | History | Annotate | Download | only in fpdfsdk
      1 // Copyright 2015 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <memory>
      6 #include <string>
      7 
      8 #include "core/fxcrt/fx_string.h"
      9 #include "public/fpdf_doc.h"
     10 #include "public/fpdf_edit.h"
     11 #include "public/fpdfview.h"
     12 #include "testing/embedder_test.h"
     13 #include "testing/fx_string_testhelpers.h"
     14 #include "testing/gtest/include/gtest/gtest.h"
     15 #include "testing/test_support.h"
     16 
     17 class FPDFDocEmbeddertest : public EmbedderTest {};
     18 
     19 TEST_F(FPDFDocEmbeddertest, DestGetPageIndex) {
     20   EXPECT_TRUE(OpenDocument("named_dests.pdf"));
     21 
     22   // NULL FPDF_DEST case.
     23   EXPECT_EQ(0U, FPDFDest_GetPageIndex(document(), nullptr));
     24 
     25   // Page number directly in item from Dests NameTree.
     26   FPDF_DEST dest = FPDF_GetNamedDestByName(document(), "First");
     27   EXPECT_TRUE(dest);
     28   EXPECT_EQ(1U, FPDFDest_GetPageIndex(document(), dest));
     29 
     30   // Page number via object reference in item from Dests NameTree.
     31   dest = FPDF_GetNamedDestByName(document(), "Next");
     32   EXPECT_TRUE(dest);
     33   EXPECT_EQ(1U, FPDFDest_GetPageIndex(document(), dest));
     34 
     35   // Page number directly in item from Dests dictionary.
     36   dest = FPDF_GetNamedDestByName(document(), "FirstAlternate");
     37   EXPECT_TRUE(dest);
     38   EXPECT_EQ(11U, FPDFDest_GetPageIndex(document(), dest));
     39 
     40   // Invalid object reference in item from Dests NameTree.
     41   dest = FPDF_GetNamedDestByName(document(), "LastAlternate");
     42   EXPECT_TRUE(dest);
     43   EXPECT_EQ(0U, FPDFDest_GetPageIndex(document(), dest));
     44 }
     45 
     46 TEST_F(FPDFDocEmbeddertest, DestGetLocationInPage) {
     47   EXPECT_TRUE(OpenDocument("named_dests.pdf"));
     48 
     49   // NULL FPDF_DEST case.
     50   EXPECT_EQ(0U, FPDFDest_GetPageIndex(document(), nullptr));
     51 
     52   FPDF_DEST dest = FPDF_GetNamedDestByName(document(), "First");
     53   EXPECT_TRUE(dest);
     54 
     55   FPDF_BOOL hasX;
     56   FPDF_BOOL hasY;
     57   FPDF_BOOL hasZoom;
     58   FS_FLOAT x;
     59   FS_FLOAT y;
     60   FS_FLOAT zoom;
     61   EXPECT_TRUE(
     62       FPDFDest_GetLocationInPage(dest, &hasX, &hasY, &hasZoom, &x, &y, &zoom));
     63   EXPECT_TRUE(hasX);
     64   EXPECT_TRUE(hasY);
     65   EXPECT_TRUE(hasZoom);
     66   EXPECT_EQ(0, x);
     67   EXPECT_EQ(0, y);
     68   EXPECT_EQ(1, zoom);
     69 }
     70 
     71 TEST_F(FPDFDocEmbeddertest, BUG_680376) {
     72   EXPECT_TRUE(OpenDocument("bug_680376.pdf"));
     73 
     74   // Page number directly in item from Dests NameTree.
     75   FPDF_DEST dest = FPDF_GetNamedDestByName(document(), "First");
     76   EXPECT_TRUE(dest);
     77   EXPECT_EQ(static_cast<unsigned long>(-1),
     78             FPDFDest_GetPageIndex(document(), dest));
     79 }
     80 
     81 TEST_F(FPDFDocEmbeddertest, ActionGetFilePath) {
     82   EXPECT_TRUE(OpenDocument("launch_action.pdf"));
     83 
     84   FPDF_PAGE page = FPDF_LoadPage(document(), 0);
     85   ASSERT_TRUE(page);
     86 
     87   // The target action is nearly the size of the whole page.
     88   FPDF_LINK link = FPDFLink_GetLinkAtPoint(page, 100, 100);
     89   ASSERT_TRUE(link);
     90 
     91   FPDF_ACTION action = FPDFLink_GetAction(link);
     92   ASSERT_TRUE(action);
     93 
     94   const char kExpectedResult[] = "test.pdf";
     95   const unsigned long kExpectedLength = sizeof(kExpectedResult);
     96   unsigned long bufsize = FPDFAction_GetFilePath(action, nullptr, 0);
     97   ASSERT_EQ(kExpectedLength, bufsize);
     98 
     99   char buf[kExpectedLength];
    100   EXPECT_EQ(bufsize, FPDFAction_GetFilePath(action, buf, bufsize));
    101   EXPECT_EQ(std::string(kExpectedResult), std::string(buf));
    102 
    103   FPDF_ClosePage(page);
    104 }
    105 
    106 TEST_F(FPDFDocEmbeddertest, NoBookmarks) {
    107   // Open a file with no bookmarks.
    108   EXPECT_TRUE(OpenDocument("named_dests.pdf"));
    109 
    110   // The non-existent top-level bookmark has no title.
    111   unsigned short buf[128];
    112   EXPECT_EQ(0u, FPDFBookmark_GetTitle(nullptr, buf, sizeof(buf)));
    113 
    114   // The non-existent top-level bookmark has no children.
    115   EXPECT_EQ(nullptr, FPDFBookmark_GetFirstChild(document(), nullptr));
    116 }
    117 
    118 TEST_F(FPDFDocEmbeddertest, Bookmarks) {
    119   // Open a file with two bookmarks.
    120   EXPECT_TRUE(OpenDocument("bookmarks.pdf"));
    121 
    122   // The existent top-level bookmark has no title.
    123   unsigned short buf[128];
    124   EXPECT_EQ(0u, FPDFBookmark_GetTitle(nullptr, buf, sizeof(buf)));
    125 
    126   FPDF_BOOKMARK child = FPDFBookmark_GetFirstChild(document(), nullptr);
    127   EXPECT_TRUE(child);
    128   EXPECT_EQ(34u, FPDFBookmark_GetTitle(child, buf, sizeof(buf)));
    129   EXPECT_EQ(CFX_WideString(L"A Good Beginning"),
    130             CFX_WideString::FromUTF16LE(buf, 16));
    131 
    132   EXPECT_EQ(nullptr, FPDFBookmark_GetFirstChild(document(), child));
    133 
    134   FPDF_BOOKMARK sibling = FPDFBookmark_GetNextSibling(document(), child);
    135   EXPECT_TRUE(sibling);
    136   EXPECT_EQ(28u, FPDFBookmark_GetTitle(sibling, buf, sizeof(buf)));
    137   EXPECT_EQ(CFX_WideString(L"A Good Ending"),
    138             CFX_WideString::FromUTF16LE(buf, 13));
    139 
    140   EXPECT_EQ(nullptr, FPDFBookmark_GetNextSibling(document(), sibling));
    141 }
    142 
    143 TEST_F(FPDFDocEmbeddertest, FindBookmarks) {
    144   // Open a file with two bookmarks.
    145   EXPECT_TRUE(OpenDocument("bookmarks.pdf"));
    146 
    147   // Find the first one, based on its known title.
    148   std::unique_ptr<unsigned short, pdfium::FreeDeleter> title =
    149       GetFPDFWideString(L"A Good Beginning");
    150   FPDF_BOOKMARK child = FPDFBookmark_Find(document(), title.get());
    151   EXPECT_TRUE(child);
    152 
    153   // Check that the string matches.
    154   unsigned short buf[128];
    155   EXPECT_EQ(34u, FPDFBookmark_GetTitle(child, buf, sizeof(buf)));
    156   EXPECT_EQ(CFX_WideString(L"A Good Beginning"),
    157             CFX_WideString::FromUTF16LE(buf, 16));
    158 
    159   // Check that it is them same as the one returned by GetFirstChild.
    160   EXPECT_EQ(child, FPDFBookmark_GetFirstChild(document(), nullptr));
    161 
    162   // Try to find one using a non-existent title.
    163   std::unique_ptr<unsigned short, pdfium::FreeDeleter> bad_title =
    164       GetFPDFWideString(L"A BAD Beginning");
    165   EXPECT_EQ(nullptr, FPDFBookmark_Find(document(), bad_title.get()));
    166 }
    167 
    168 // Check circular bookmarks will not cause infinite loop.
    169 TEST_F(FPDFDocEmbeddertest, FindBookmarks_bug420) {
    170   // Open a file with circular bookmarks.
    171   EXPECT_TRUE(OpenDocument("bookmarks_circular.pdf"));
    172 
    173   // Try to find a title.
    174   std::unique_ptr<unsigned short, pdfium::FreeDeleter> title =
    175       GetFPDFWideString(L"anything");
    176   EXPECT_EQ(nullptr, FPDFBookmark_Find(document(), title.get()));
    177 }
    178 
    179 TEST_F(FPDFDocEmbeddertest, DeletePage) {
    180   EXPECT_TRUE(OpenDocument("hello_world.pdf"));
    181   EXPECT_EQ(1, FPDF_GetPageCount(document()));
    182   FPDFPage_Delete(document(), 0);
    183   EXPECT_EQ(0, FPDF_GetPageCount(document()));
    184 }
    185 
    186 TEST_F(FPDFDocEmbeddertest, NoPageLabels) {
    187   EXPECT_TRUE(OpenDocument("about_blank.pdf"));
    188   EXPECT_EQ(1, FPDF_GetPageCount(document()));
    189 
    190   ASSERT_EQ(0u, FPDF_GetPageLabel(document(), 0, nullptr, 0));
    191 }
    192 
    193 TEST_F(FPDFDocEmbeddertest, GetPageLabels) {
    194   EXPECT_TRUE(OpenDocument("page_labels.pdf"));
    195   EXPECT_EQ(7, FPDF_GetPageCount(document()));
    196 
    197   unsigned short buf[128];
    198   EXPECT_EQ(0u, FPDF_GetPageLabel(document(), -2, buf, sizeof(buf)));
    199   EXPECT_EQ(0u, FPDF_GetPageLabel(document(), -1, buf, sizeof(buf)));
    200 
    201   const FX_WCHAR kExpectedPageLabel0[] = L"i";
    202   ASSERT_EQ(4u, FPDF_GetPageLabel(document(), 0, buf, sizeof(buf)));
    203   EXPECT_EQ(CFX_WideString(kExpectedPageLabel0),
    204             CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel0)));
    205 
    206   const FX_WCHAR kExpectedPageLabel1[] = L"ii";
    207   ASSERT_EQ(6u, FPDF_GetPageLabel(document(), 1, buf, sizeof(buf)));
    208   EXPECT_EQ(CFX_WideString(kExpectedPageLabel1),
    209             CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel1)));
    210 
    211   const FX_WCHAR kExpectedPageLabel2[] = L"1";
    212   ASSERT_EQ(4u, FPDF_GetPageLabel(document(), 2, buf, sizeof(buf)));
    213   EXPECT_EQ(CFX_WideString(kExpectedPageLabel2),
    214             CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel2)));
    215 
    216   const FX_WCHAR kExpectedPageLabel3[] = L"2";
    217   ASSERT_EQ(4u, FPDF_GetPageLabel(document(), 3, buf, sizeof(buf)));
    218   EXPECT_EQ(CFX_WideString(kExpectedPageLabel3),
    219             CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel3)));
    220 
    221   const FX_WCHAR kExpectedPageLabel4[] = L"zzA";
    222   ASSERT_EQ(8u, FPDF_GetPageLabel(document(), 4, buf, sizeof(buf)));
    223   EXPECT_EQ(CFX_WideString(kExpectedPageLabel4),
    224             CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel4)));
    225 
    226   const FX_WCHAR kExpectedPageLabel5[] = L"zzB";
    227   ASSERT_EQ(8u, FPDF_GetPageLabel(document(), 5, buf, sizeof(buf)));
    228   EXPECT_EQ(CFX_WideString(kExpectedPageLabel5),
    229             CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel5)));
    230 
    231   const FX_WCHAR kExpectedPageLabel6[] = L"";
    232   ASSERT_EQ(2u, FPDF_GetPageLabel(document(), 6, buf, sizeof(buf)));
    233   EXPECT_EQ(CFX_WideString(kExpectedPageLabel6),
    234             CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel6)));
    235 
    236   ASSERT_EQ(0u, FPDF_GetPageLabel(document(), 7, buf, sizeof(buf)));
    237   ASSERT_EQ(0u, FPDF_GetPageLabel(document(), 8, buf, sizeof(buf)));
    238 }
    239