Add support for action /GoToE Add support for action /GoToE, to allow embedders to get the file path and destination associated to this action. Change-Id: I49eeef889da6babcd212a56f6cc0b291d76b942c Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/72530 Commit-Queue: Lei Zhang <thestig@chromium.org> Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfdoc/cpdf_action.cpp b/core/fpdfdoc/cpdf_action.cpp index 9166b7c..deb9af8 100644 --- a/core/fpdfdoc/cpdf_action.cpp +++ b/core/fpdfdoc/cpdf_action.cpp
@@ -54,14 +54,15 @@ CPDF_Dest CPDF_Action::GetDest(CPDF_Document* pDoc) const { ActionType type = GetType(); - if (type != GoTo && type != GoToR) + if (type != GoTo && type != GoToR && type != GoToE) { return CPDF_Dest(nullptr); + } return CPDF_Dest::Create(pDoc, m_pDict->GetDirectObjectFor("D")); } WideString CPDF_Action::GetFilePath() const { ActionType type = GetType(); - if (type != GoToR && type != Launch && type != SubmitForm && + if (type != GoToR && type != GoToE && type != Launch && type != SubmitForm && type != ImportData) { return WideString(); }
diff --git a/fpdfsdk/fpdf_doc.cpp b/fpdfsdk/fpdf_doc.cpp index e85e530..b6a5ed4 100644 --- a/fpdfsdk/fpdf_doc.cpp +++ b/fpdfsdk/fpdf_doc.cpp
@@ -163,6 +163,8 @@ return PDFACTION_GOTO; case CPDF_Action::GoToR: return PDFACTION_REMOTEGOTO; + case CPDF_Action::GoToE: + return PDFACTION_EMBEDDEDGOTO; case CPDF_Action::URI: return PDFACTION_URI; case CPDF_Action::Launch: @@ -179,9 +181,10 @@ return nullptr; unsigned long type = FPDFAction_GetType(action); - if (type != PDFACTION_GOTO && type != PDFACTION_REMOTEGOTO) + if (type != PDFACTION_GOTO && type != PDFACTION_REMOTEGOTO && + type != PDFACTION_EMBEDDEDGOTO) { return nullptr; - + } CPDF_Action cAction(CPDFDictionaryFromFPDFAction(action)); return FPDFDestFromCPDFArray(cAction.GetDest(pDoc).GetArray()); } @@ -189,8 +192,10 @@ FPDF_EXPORT unsigned long FPDF_CALLCONV FPDFAction_GetFilePath(FPDF_ACTION action, void* buffer, unsigned long buflen) { unsigned long type = FPDFAction_GetType(action); - if (type != PDFACTION_REMOTEGOTO && type != PDFACTION_LAUNCH) + if (type != PDFACTION_REMOTEGOTO && type != PDFACTION_EMBEDDEDGOTO && + type != PDFACTION_LAUNCH) { return 0; + } CPDF_Action cAction(CPDFDictionaryFromFPDFAction(action)); ByteString path = cAction.GetFilePath().ToUTF8();
diff --git a/fpdfsdk/fpdf_doc_embeddertest.cpp b/fpdfsdk/fpdf_doc_embeddertest.cpp index 652d565..24f57a9 100644 --- a/fpdfsdk/fpdf_doc_embeddertest.cpp +++ b/fpdfsdk/fpdf_doc_embeddertest.cpp
@@ -388,6 +388,43 @@ UnloadPage(page); } +TEST_F(FPDFDocEmbedderTest, ActionEmbeddedGoto) { + ASSERT_TRUE(OpenDocument("gotoe_action.pdf")); + + FPDF_PAGE page = LoadPage(0); + ASSERT_TRUE(page); + + // The target action is nearly the size of the whole page. + FPDF_LINK link = FPDFLink_GetLinkAtPoint(page, 100, 100); + ASSERT_TRUE(link); + + FPDF_ACTION action = FPDFLink_GetAction(link); + ASSERT_TRUE(action); + EXPECT_EQ(static_cast<unsigned long>(PDFACTION_EMBEDDEDGOTO), + FPDFAction_GetType(action)); + + FPDF_DEST dest = FPDFAction_GetDest(document(), action); + EXPECT_TRUE(dest); + + unsigned long num_params = 42; + FS_FLOAT params[4]; + std::fill_n(params, 4, 42.4242f); + EXPECT_EQ(static_cast<unsigned long>(PDFDEST_VIEW_FIT), + FPDFDest_GetView(dest, &num_params, params)); + EXPECT_EQ(0u, num_params); + EXPECT_FLOAT_EQ(42.4242f, params[0]); + + const char kExpectedResult[] = "ExampleFile.pdf"; + const unsigned long kExpectedLength = sizeof(kExpectedResult); + char buf[1024]; + unsigned long bufsize = FPDFAction_GetFilePath(action, nullptr, 0); + EXPECT_EQ(kExpectedLength, bufsize); + EXPECT_EQ(kExpectedLength, FPDFAction_GetFilePath(action, buf, bufsize)); + EXPECT_STREQ(kExpectedResult, buf); + + UnloadPage(page); +} + TEST_F(FPDFDocEmbedderTest, ActionNonesuch) { ASSERT_TRUE(OpenDocument("nonesuch_action.pdf"));
diff --git a/public/fpdf_doc.h b/public/fpdf_doc.h index 1c8cf3b..6355ec6 100644 --- a/public/fpdf_doc.h +++ b/public/fpdf_doc.h
@@ -24,6 +24,8 @@ #define PDFACTION_URI 3 // Launch an application or open a file. #define PDFACTION_LAUNCH 4 +// Go to a destination in an embedded file. +#define PDFACTION_EMBEDDEDGOTO 5 // View destination fit types. See pdfmark reference v9, page 48. #define PDFDEST_VIEW_UNKNOWN_MODE 0
diff --git a/testing/resources/gotoe_action.in b/testing/resources/gotoe_action.in new file mode 100644 index 0000000..04b7cf0 --- /dev/null +++ b/testing/resources/gotoe_action.in
@@ -0,0 +1,48 @@ +{{header}} +{{object 1 0}} << + /Type /Catalog + /Pages 2 0 R +>> +endobj +{{object 2 0}} << + /Type /Pages + /MediaBox [0 0 200 200] + /Count 1 + /Kids [3 0 R] +>> +endobj +{{object 3 0}} << + /Type /Page + /Parent 2 0 R + /Annots [4 0 R] +>> +endobj +{{object 4 0}} << + /Type /Annot + /Subtype /Link + /FT /Tx + /Ff 29360128 + /A 5 0 R + /T (txtName) + /F 4 + /M (D:20150514070426+05'30') + /Rect [1 1 199 199] + /BS << + /W 1 + /S /S + >> + /DA (/Helv 0 Tf 0 0 0 rg) + /V () +>> +endobj +{{object 5 0}} << + /S /GoToE + /D [1 /Fit] + /F (ExampleFile.pdf) +>> +>> +endobj +{{xref}} +{{trailer}} +{{startxref}} +%%EOF
diff --git a/testing/resources/gotoe_action.pdf b/testing/resources/gotoe_action.pdf new file mode 100644 index 0000000..8d588e0 --- /dev/null +++ b/testing/resources/gotoe_action.pdf
@@ -0,0 +1,60 @@ +%PDF-1.7 +% ò¤ô +1 0 obj << + /Type /Catalog + /Pages 2 0 R +>> +endobj +2 0 obj << + /Type /Pages + /MediaBox [0 0 200 200] + /Count 1 + /Kids [3 0 R] +>> +endobj +3 0 obj << + /Type /Page + /Parent 2 0 R + /Annots [4 0 R] +>> +endobj +4 0 obj << + /Type /Annot + /Subtype /Link + /FT /Tx + /Ff 29360128 + /A 5 0 R + /T (txtName) + /F 4 + /M (D:20150514070426+05'30') + /Rect [1 1 199 199] + /BS << + /W 1 + /S /S + >> + /DA (/Helv 0 Tf 0 0 0 rg) + /V () +>> +endobj +5 0 obj << + /S /GoToE + /D [1 /Fit] + /F (ExampleFile.pdf) +>> +>> +endobj +xref +0 6 +0000000000 65535 f +0000000015 00000 n +0000000068 00000 n +0000000157 00000 n +0000000226 00000 n +0000000460 00000 n +trailer << + /Root 1 0 R + /Size 6 +>> +startxref +533 +%%EOF