From e0947b37c012144cefb523a33e548d3fadc211d8 Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Thu, 17 Sep 2015 14:51:48 -0700 Subject: Merge to XFA: Implement FPDFAction_GetFilePath(). The API is the same as the Foxit version, except the encoding is specified as UTF-8 instead of local encoding. Also remove CPDF_LWinParam since it's unused. BUG=chromium:517713 R=tsepez@chromium.org Review URL: https://codereview.chromium.org/1335373002 . (cherry picked from commit 0b3c8f742613da294f812e2f6e908f4026499f96) (cherry picked from commit a9d4bc541179ec0436adc4b2e18b7fdecc5952dc) (cherry picked from commit 4ffd89ed556e32a6527d0e88952fe20ec1e2f362) Review URL: https://codereview.chromium.org/1345953002 . --- core/include/fpdfdoc/fpdf_doc.h | 20 ----------- core/src/fpdfdoc/doc_action.cpp | 10 +----- fpdfsdk/src/fpdfdoc.cpp | 49 ++++++++++++++++----------- fpdfsdk/src/fpdfdoc_embeddertest.cpp | 25 ++++++++++++++ fpdfsdk/src/fpdfview_c_api_test.c | 1 + public/fpdf_doc.h | 34 ++++++++++++++----- testing/resources/launch_action.in | 54 ++++++++++++++++++++++++++++++ testing/resources/launch_action.pdf | 64 ++++++++++++++++++++++++++++++++++++ 8 files changed, 200 insertions(+), 57 deletions(-) create mode 100644 testing/resources/launch_action.in create mode 100644 testing/resources/launch_action.pdf diff --git a/core/include/fpdfdoc/fpdf_doc.h b/core/include/fpdfdoc/fpdf_doc.h index eb99e9234a..b2ac747427 100644 --- a/core/include/fpdfdoc/fpdf_doc.h +++ b/core/include/fpdfdoc/fpdf_doc.h @@ -33,7 +33,6 @@ class CPDF_FormNotify; class CPDF_IconFit; class CPDF_InterForm; class CPDF_Link; -class CPDF_LWinParam; class CPDF_Metadata; class CPDF_NumberTree; class CPDF_OCContext; @@ -163,24 +162,7 @@ class CPDF_OCContext : public IPDF_OCContext { std::map m_OCGStates; }; -class CPDF_LWinParam { - public: - CPDF_LWinParam(CPDF_Dictionary* pDict) { m_pDict = pDict; } - - operator CPDF_Dictionary*() const { return m_pDict; } - - inline CFX_ByteString GetFileName() { return m_pDict->GetString("F"); } - - inline CFX_ByteString GetDefaultDirectory() { - return m_pDict->GetString("D"); - } - inline CFX_ByteString GetOperation() { return m_pDict->GetString("O"); } - - inline CFX_ByteString GetParameter() { return m_pDict->GetString("P"); } - - CPDF_Dictionary* m_pDict; -}; class CPDF_ActionFields { public: CPDF_ActionFields(const CPDF_Action* pAction) { @@ -244,8 +226,6 @@ class CPDF_Action { FX_BOOL GetNewWindow() const { return m_pDict->GetBoolean("NewWindow"); } - CPDF_LWinParam GetWinParam() const; - CFX_ByteString GetURI(CPDF_Document* pDoc) const; FX_BOOL GetMouseMap() const { return m_pDict->GetBoolean("IsMap"); } diff --git a/core/src/fpdfdoc/doc_action.cpp b/core/src/fpdfdoc/doc_action.cpp index f8a11e5682..759a06c656 100644 --- a/core/src/fpdfdoc/doc_action.cpp +++ b/core/src/fpdfdoc/doc_action.cpp @@ -179,15 +179,7 @@ CPDF_Object* CPDF_ActionFields::GetField(FX_DWORD iIndex) const { } return pFindObj; } -CPDF_LWinParam CPDF_Action::GetWinParam() const { - if (m_pDict == NULL) { - return NULL; - } - if (m_pDict->GetString("S") != "Launch") { - return NULL; - } - return m_pDict->GetDict("Win"); -} + CFX_WideString CPDF_Action::GetJavaScript() const { CFX_WideString csJS; if (m_pDict == NULL) { diff --git a/fpdfsdk/src/fpdfdoc.cpp b/fpdfsdk/src/fpdfdoc.cpp index 47225dd2b1..34caf95b52 100644 --- a/fpdfsdk/src/fpdfdoc.cpp +++ b/fpdfsdk/src/fpdfdoc.cpp @@ -128,7 +128,8 @@ DLLEXPORT FPDF_ACTION STDCALL FPDFBookmark_GetAction(FPDF_BOOKMARK pDict) { DLLEXPORT unsigned long STDCALL FPDFAction_GetType(FPDF_ACTION pDict) { if (!pDict) - return 0; + return PDFACTION_UNSUPPORTED; + CPDF_Action action((CPDF_Dictionary*)pDict); CPDF_Action::ActionType type = action.GetType(); switch (type) { @@ -143,43 +144,53 @@ DLLEXPORT unsigned long STDCALL FPDFAction_GetType(FPDF_ACTION pDict) { default: return PDFACTION_UNSUPPORTED; } - return PDFACTION_UNSUPPORTED; } DLLEXPORT FPDF_DEST STDCALL FPDFAction_GetDest(FPDF_DOCUMENT document, FPDF_ACTION pDict) { - if (!document) - return NULL; - if (!pDict) - return NULL; + if (!document || !pDict) + return nullptr; + CPDF_Document* pDoc = ((CPDFXFA_Document*)document)->GetPDFDoc(); CPDF_Action action((CPDF_Dictionary*)pDict); return action.GetDest(pDoc).GetObject(); } +DLLEXPORT unsigned long STDCALL +FPDFAction_GetFilePath(FPDF_ACTION pDict, void* buffer, unsigned long buflen) { + unsigned long type = FPDFAction_GetType(pDict); + if (type != PDFACTION_REMOTEGOTO && type != PDFACTION_LAUNCH) + return 0; + + CPDF_Action action((CPDF_Dictionary*)pDict); + CFX_ByteString path = action.GetFilePath().UTF8Encode(); + unsigned long len = path.GetLength() + 1; + if (buffer && buflen >= len) + FXSYS_memcpy(buffer, path.c_str(), len); + return len; +} + DLLEXPORT unsigned long STDCALL FPDFAction_GetURIPath(FPDF_DOCUMENT document, FPDF_ACTION pDict, void* buffer, unsigned long buflen) { - if (!document) - return 0; - if (!pDict) + if (!document || !pDict) return 0; + CPDF_Document* pDoc = ((CPDFXFA_Document*)document)->GetPDFDoc(); CPDF_Action action((CPDF_Dictionary*)pDict); CFX_ByteString path = action.GetURI(pDoc); unsigned long len = path.GetLength() + 1; - if (buffer != NULL && buflen >= len) + if (buffer && buflen >= len) FXSYS_memcpy(buffer, path.c_str(), len); return len; } DLLEXPORT unsigned long STDCALL FPDFDest_GetPageIndex(FPDF_DOCUMENT document, FPDF_DEST pDict) { - if (!document) - return 0; - if (!pDict) + if (!document || !pDict) return 0; + CPDF_Document* pDoc = ((CPDFXFA_Document*)document)->GetPDFDoc(); CPDF_Dest dest((CPDF_Array*)pDict); return dest.GetPageIndex(pDoc); @@ -218,10 +229,9 @@ FPDFLink_GetLinkZOrderAtPoint(FPDF_PAGE page, double x, double y) { DLLEXPORT FPDF_DEST STDCALL FPDFLink_GetDest(FPDF_DOCUMENT document, FPDF_LINK pDict) { - if (!document) - return NULL; - if (!pDict) - return NULL; + if (!document || !pDict) + return nullptr; + CPDF_Document* pDoc = ((CPDFXFA_Document*)document)->GetPDFDoc(); CPDF_Link link((CPDF_Dictionary*)pDict); FPDF_DEST dest = link.GetDest(pDoc).GetObject(); @@ -230,13 +240,14 @@ DLLEXPORT FPDF_DEST STDCALL FPDFLink_GetDest(FPDF_DOCUMENT document, // If this link is not directly associated with a dest, we try to get action CPDF_Action action = link.GetAction(); if (!action) - return NULL; + return nullptr; return action.GetDest(pDoc).GetObject(); } DLLEXPORT FPDF_ACTION STDCALL FPDFLink_GetAction(FPDF_LINK pDict) { if (!pDict) - return NULL; + return nullptr; + CPDF_Link link((CPDF_Dictionary*)pDict); return link.GetAction().GetDict(); } diff --git a/fpdfsdk/src/fpdfdoc_embeddertest.cpp b/fpdfsdk/src/fpdfdoc_embeddertest.cpp index b263fafe16..8b1c4fb3e8 100644 --- a/fpdfsdk/src/fpdfdoc_embeddertest.cpp +++ b/fpdfsdk/src/fpdfdoc_embeddertest.cpp @@ -35,3 +35,28 @@ TEST_F(FPDFDocEmbeddertest, DestGetPageIndex) { EXPECT_NE(nullptr, dest); EXPECT_EQ(0U, FPDFDest_GetPageIndex(document(), dest)); } + +TEST_F(FPDFDocEmbeddertest, ActionGetFilePath) { + EXPECT_TRUE(OpenDocument("testing/resources/launch_action.pdf")); + + FPDF_PAGE page = FPDF_LoadPage(document(), 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); + + const char kExpectedResult[] = "test.pdf"; + const unsigned long kExpectedLength = sizeof(kExpectedResult); + unsigned long bufsize = FPDFAction_GetFilePath(action, nullptr, 0); + ASSERT_EQ(kExpectedLength, bufsize); + + char buf[kExpectedLength]; + EXPECT_EQ(bufsize, FPDFAction_GetFilePath(action, buf, bufsize)); + EXPECT_EQ(std::string(kExpectedResult), std::string(buf)); + + FPDF_ClosePage(page); +} diff --git a/fpdfsdk/src/fpdfview_c_api_test.c b/fpdfsdk/src/fpdfview_c_api_test.c index 01789b4432..d16bf99f07 100644 --- a/fpdfsdk/src/fpdfview_c_api_test.c +++ b/fpdfsdk/src/fpdfview_c_api_test.c @@ -51,6 +51,7 @@ int CheckPDFiumCApi() { CHK(FPDFBookmark_GetAction); CHK(FPDFAction_GetType); CHK(FPDFAction_GetDest); + CHK(FPDFAction_GetFilePath); CHK(FPDFAction_GetURIPath); CHK(FPDFDest_GetPageIndex); CHK(FPDFLink_GetLinkAtPoint); diff --git a/public/fpdf_doc.h b/public/fpdf_doc.h index ca16d26627..49793e6b19 100644 --- a/public/fpdf_doc.h +++ b/public/fpdf_doc.h @@ -110,10 +110,9 @@ DLLEXPORT FPDF_ACTION STDCALL FPDFBookmark_GetAction(FPDF_BOOKMARK bookmark); #define PDFACTION_UNSUPPORTED 0 // Unsupported action type. #define PDFACTION_GOTO 1 // Go to a destination within current document. #define PDFACTION_REMOTEGOTO 2 // Go to a destination within another document. -#define PDFACTION_URI \ - 3 // Universal Resource Identifier, including web pages and - // other Internet based resources. -#define PDFACTION_LAUNCH 4 // Launch an application or open a file. +#define PDFACTION_URI 3 // Universal Resource Identifier, including web + // pages and other Internet based resources. +#define PDFACTION_LAUNCH 4 // Launch an application or open a file. // Function: FPDFAction_GetType // Get type of an action. @@ -142,6 +141,25 @@ DLLEXPORT unsigned long STDCALL FPDFAction_GetType(FPDF_ACTION action); DLLEXPORT FPDF_DEST STDCALL FPDFAction_GetDest(FPDF_DOCUMENT document, FPDF_ACTION action); +// Function: FPDFAction_GetFilePath +// Get file path of a remote goto action. +// Parameters: +// action - Handle to the action. Must be a REMOTEGOTO or +// LAUNCH action. +// buffer - A buffer for output the path string. Can be NULL. +// buflen - The length of the buffer, number of bytes. Can be 0. +// Return value: +// Number of bytes the file path consumes, including trailing zero. +// +// Comments: +// The file path is UTF-8 encoded. The return value is the number of +// bytes required for the buffer, even when there is no buffer +// specified, or the buffer size is less then required. In this case, +// the buffer will not be modified. +// +DLLEXPORT unsigned long STDCALL +FPDFAction_GetFilePath(FPDF_ACTION action, void* buffer, unsigned long buflen); + // Function: FPDFAction_GetURIPath // Get URI path of a URI action. // Parameters: @@ -154,11 +172,9 @@ DLLEXPORT FPDF_DEST STDCALL FPDFAction_GetDest(FPDF_DOCUMENT document, // Comments: // The URI path is always encoded in 7-bit ASCII. // -// The return value always indicated number of bytes required for the -// buffer, even when there is -// no buffer specified, or the buffer size is less then required. In -// this case, the buffer will not -// be modified. +// The return value is the number of bytes required for the buffer, +// even when there is no buffer specified, or the buffer size is less +// then required. In this case, the buffer will not be modified. // DLLEXPORT unsigned long STDCALL FPDFAction_GetURIPath(FPDF_DOCUMENT document, FPDF_ACTION action, diff --git a/testing/resources/launch_action.in b/testing/resources/launch_action.in new file mode 100644 index 0000000000..c98539f5ea --- /dev/null +++ b/testing/resources/launch_action.in @@ -0,0 +1,54 @@ +{{header}} +{{object 1 0}} << + /Type /Catalog + /Pages 2 0 R +>> +{{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}} << + /A 5 0 R + /FT /Tx + /Ff 29360128 + /T (txtName) + /Type /Annot + /Subtype /Link + /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) + /AP <> + /V () + /AA 19 0 R +>> +endobj +{{object 5 0}} << + /F 6 0 R + /S /Launch +>> +{{object 6 0}} << + /F (test.pdf) + /Type / Filespec +>> +endobj +{{xref}} +trailer << + /Size 6 + /Root 1 0 R +>> +{{startxref}} +%%EOF diff --git a/testing/resources/launch_action.pdf b/testing/resources/launch_action.pdf new file mode 100644 index 0000000000..99a42923de --- /dev/null +++ b/testing/resources/launch_action.pdf @@ -0,0 +1,64 @@ +%PDF-1.7 +% ò¤ô +1 0 obj << + /Type /Catalog + /Pages 2 0 R +>> +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 << + /A 5 0 R + /FT /Tx + /Ff 29360128 + /T (txtName) + /Type /Annot + /Subtype /Link + /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) + /AP <> + /V () + /AA 19 0 R +>> +endobj +5 0 obj << + /F 6 0 R + /S /Launch +>> +6 0 obj << + /F (test.pdf) + /Type / Filespec +>> +endobj +xref +0 7 +0000000000 65535 f +0000000015 00000 n +0000000061 00000 n +0000000154 00000 n +0000000223 00000 n +0000000489 00000 n +0000000527 00000 n +trailer << + /Size 6 + /Root 1 0 R +>> +startxref +583 +%%EOF -- cgit v1.2.3