summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/include/fpdfdoc/fpdf_doc.h20
-rw-r--r--core/src/fpdfdoc/doc_action.cpp10
-rw-r--r--fpdfsdk/src/fpdfdoc.cpp49
-rw-r--r--fpdfsdk/src/fpdfdoc_embeddertest.cpp25
-rw-r--r--fpdfsdk/src/fpdfview_c_api_test.c1
-rw-r--r--public/fpdf_doc.h34
-rw-r--r--testing/resources/launch_action.in54
-rw-r--r--testing/resources/launch_action.pdf64
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