diff options
-rw-r--r-- | core/include/fpdfdoc/fpdf_doc.h | 20 | ||||
-rw-r--r-- | core/src/fpdfdoc/doc_action.cpp | 10 | ||||
-rw-r--r-- | fpdfsdk/src/fpdfdoc.cpp | 49 | ||||
-rw-r--r-- | fpdfsdk/src/fpdfdoc_embeddertest.cpp | 25 | ||||
-rw-r--r-- | fpdfsdk/src/fpdfview_c_api_test.c | 1 | ||||
-rw-r--r-- | public/fpdf_doc.h | 34 | ||||
-rw-r--r-- | testing/resources/launch_action.in | 54 | ||||
-rw-r--r-- | testing/resources/launch_action.pdf | 64 |
8 files changed, 200 insertions, 57 deletions
diff --git a/core/include/fpdfdoc/fpdf_doc.h b/core/include/fpdfdoc/fpdf_doc.h index 2d37a48153..0588a3a914 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<const CPDF_Dictionary*, FX_BOOL> 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 5d2469c160..97f5cf3c6d 100644 --- a/fpdfsdk/src/fpdfdoc.cpp +++ b/fpdfsdk/src/fpdfdoc.cpp @@ -126,7 +126,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) { @@ -141,43 +142,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 = (CPDF_Document*)document; 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 = (CPDF_Document*)document; 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 = (CPDF_Document*)document; CPDF_Dest dest((CPDF_Array*)pDict); return dest.GetPageIndex(pDoc); @@ -208,10 +219,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 = (CPDF_Document*)document; CPDF_Link link((CPDF_Dictionary*)pDict); FPDF_DEST dest = link.GetDest(pDoc).GetObject(); @@ -220,13 +230,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..f3663baf10 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 = strlen(kExpectedResult) + 1; + 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 9bd2747f83..0d212558e7 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 e537d2b6c1..de05eb3a59 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 <</N 8 0 R>> + /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 <</N 8 0 R>> + /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 |