Implement FPDFAction_GetFilePath().
authorLei Zhang <thestig@chromium.org>
Tue, 15 Sep 2015 21:45:29 +0000 (14:45 -0700)
committerLei Zhang <thestig@chromium.org>
Tue, 15 Sep 2015 21:45:29 +0000 (14:45 -0700)
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=jun_fang@foxitsoftware.com

Review URL: https://codereview.chromium.org/1335373002 .

core/include/fpdfdoc/fpdf_doc.h
core/src/fpdfdoc/doc_action.cpp
fpdfsdk/src/fpdfdoc.cpp
fpdfsdk/src/fpdfdoc_embeddertest.cpp
fpdfsdk/src/fpdfview_c_api_test.c
public/fpdf_doc.h
testing/resources/launch_action.in [new file with mode: 0644]
testing/resources/launch_action.pdf [new file with mode: 0644]

index 2d37a48..0588a3a 100644 (file)
@@ -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"); }
index f8a11e5..759a06c 100644 (file)
@@ -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) {
index 5d2469c..97f5cf3 100644 (file)
@@ -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();
 }
index b263faf..f3663ba 100644 (file)
@@ -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);
+}
index 9bd2747..0d21255 100644 (file)
@@ -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);
index e537d2b..de05eb3 100644 (file)
@@ -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 (file)
index 0000000..c98539f
--- /dev/null
@@ -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 (file)
index 0000000..99a4292
--- /dev/null
@@ -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