blob: 4ac86fe1048a70815411c3eafadd676339453724 [file] [log] [blame]
dsinclair02e6f592016-08-02 11:25:48 -07001// Copyright 2016 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
dsinclair1727aee2016-09-29 13:12:56 -07007#include "core/fpdfdoc/cpdf_action.h"
dsinclair02e6f592016-08-02 11:25:48 -07008
Lei Zhang26170562018-04-17 17:01:52 +00009#include "constants/stream_dict_common.h"
dsinclair488b7ad2016-10-04 11:55:50 -070010#include "core/fpdfapi/parser/cpdf_array.h"
11#include "core/fpdfapi/parser/cpdf_document.h"
dsinclair1727aee2016-09-29 13:12:56 -070012#include "core/fpdfdoc/cpdf_filespec.h"
13#include "core/fpdfdoc/cpdf_nametree.h"
dsinclair02e6f592016-08-02 11:25:48 -070014
15namespace {
16
Dan Sinclair812e96c2017-03-13 16:43:37 -040017const char* const g_sATypes[] = {
dsinclair02e6f592016-08-02 11:25:48 -070018 "Unknown", "GoTo", "GoToR", "GoToE", "Launch",
19 "Thread", "URI", "Sound", "Movie", "Hide",
20 "Named", "SubmitForm", "ResetForm", "ImportData", "JavaScript",
21 "SetOCGState", "Rendition", "Trans", "GoTo3DView", nullptr};
22
23} // namespace
24
Tom Sepez797ca5c2017-05-25 12:03:18 -070025CPDF_Action::CPDF_Action(CPDF_Dictionary* pDict) : m_pDict(pDict) {}
26
27CPDF_Action::CPDF_Action(const CPDF_Action& that) = default;
28
29CPDF_Action::~CPDF_Action() {}
30
dsinclair02e6f592016-08-02 11:25:48 -070031CPDF_Dest CPDF_Action::GetDest(CPDF_Document* pDoc) const {
32 if (!m_pDict)
33 return CPDF_Dest();
34
Ryan Harrison275e2602017-09-18 14:23:18 -040035 ByteString type = m_pDict->GetStringFor("S");
dsinclair02e6f592016-08-02 11:25:48 -070036 if (type != "GoTo" && type != "GoToR")
37 return CPDF_Dest();
38
dsinclair38fd8442016-09-15 10:15:32 -070039 CPDF_Object* pDest = m_pDict->GetDirectObjectFor("D");
dsinclair02e6f592016-08-02 11:25:48 -070040 if (!pDest)
41 return CPDF_Dest();
42 if (pDest->IsString() || pDest->IsName()) {
43 CPDF_NameTree name_tree(pDoc, "Dests");
Jane Liu67ccef72017-07-19 13:10:50 -040044 return CPDF_Dest(name_tree.LookupNamedDest(pDoc, pDest->GetUnicodeText()));
dsinclair02e6f592016-08-02 11:25:48 -070045 }
46 if (CPDF_Array* pArray = pDest->AsArray())
47 return CPDF_Dest(pArray);
48
49 return CPDF_Dest();
50}
51
52CPDF_Action::ActionType CPDF_Action::GetType() const {
53 if (!m_pDict)
54 return Unknown;
55
Ryan Harrison275e2602017-09-18 14:23:18 -040056 ByteString csType = m_pDict->GetStringFor("S");
dsinclair02e6f592016-08-02 11:25:48 -070057 if (csType.IsEmpty())
58 return Unknown;
59
60 for (int i = 0; g_sATypes[i]; ++i) {
61 if (csType == g_sATypes[i])
62 return static_cast<ActionType>(i);
63 }
64 return Unknown;
65}
66
Ryan Harrison275e2602017-09-18 14:23:18 -040067WideString CPDF_Action::GetFilePath() const {
68 ByteString type = m_pDict->GetStringFor("S");
dsinclair02e6f592016-08-02 11:25:48 -070069 if (type != "GoToR" && type != "Launch" && type != "SubmitForm" &&
70 type != "ImportData") {
Ryan Harrison275e2602017-09-18 14:23:18 -040071 return WideString();
dsinclair02e6f592016-08-02 11:25:48 -070072 }
73
Lei Zhang26170562018-04-17 17:01:52 +000074 CPDF_Object* pFile = m_pDict->GetDirectObjectFor(pdfium::stream::kF);
Jane Liuc8a17e52017-07-13 10:37:59 -040075 if (pFile)
76 return CPDF_FileSpec(pFile).GetFileName();
dsinclair02e6f592016-08-02 11:25:48 -070077
Jane Liuc8a17e52017-07-13 10:37:59 -040078 if (type == "Launch") {
79 CPDF_Dictionary* pWinDict = m_pDict->GetDictFor("Win");
80 if (pWinDict) {
Lei Zhang26170562018-04-17 17:01:52 +000081 return WideString::FromLocal(
82 pWinDict->GetStringFor(pdfium::stream::kF).AsStringView());
Jane Liuc8a17e52017-07-13 10:37:59 -040083 }
84 }
Ryan Harrison275e2602017-09-18 14:23:18 -040085 return WideString();
dsinclair02e6f592016-08-02 11:25:48 -070086}
87
Ryan Harrison275e2602017-09-18 14:23:18 -040088ByteString CPDF_Action::GetURI(const CPDF_Document* pDoc) const {
89 ByteString csURI;
dsinclair02e6f592016-08-02 11:25:48 -070090 if (!m_pDict)
91 return csURI;
dsinclair38fd8442016-09-15 10:15:32 -070092 if (m_pDict->GetStringFor("S") != "URI")
dsinclair02e6f592016-08-02 11:25:48 -070093 return csURI;
94
dsinclair38fd8442016-09-15 10:15:32 -070095 csURI = m_pDict->GetStringFor("URI");
Lei Zhang01581062017-08-30 14:19:26 -070096 const CPDF_Dictionary* pRoot = pDoc->GetRoot();
dsinclair38fd8442016-09-15 10:15:32 -070097 CPDF_Dictionary* pURI = pRoot->GetDictFor("URI");
dsinclair02e6f592016-08-02 11:25:48 -070098 if (pURI) {
Ryan Harrison12db7512017-08-23 10:39:35 -040099 auto result = csURI.Find(":");
100 if (!result.has_value() || result.value() == 0)
dsinclair38fd8442016-09-15 10:15:32 -0700101 csURI = pURI->GetStringFor("Base") + csURI;
dsinclair02e6f592016-08-02 11:25:48 -0700102 }
103 return csURI;
104}
105
Ryan Harrison275e2602017-09-18 14:23:18 -0400106WideString CPDF_Action::GetJavaScript() const {
107 WideString csJS;
dsinclair02e6f592016-08-02 11:25:48 -0700108 if (!m_pDict)
109 return csJS;
110
dsinclair38fd8442016-09-15 10:15:32 -0700111 CPDF_Object* pJS = m_pDict->GetDirectObjectFor("JS");
dsinclair02e6f592016-08-02 11:25:48 -0700112 return pJS ? pJS->GetUnicodeText() : csJS;
113}
114
115size_t CPDF_Action::GetSubActionsCount() const {
116 if (!m_pDict || !m_pDict->KeyExist("Next"))
117 return 0;
118
dsinclair38fd8442016-09-15 10:15:32 -0700119 CPDF_Object* pNext = m_pDict->GetDirectObjectFor("Next");
dsinclair02e6f592016-08-02 11:25:48 -0700120 if (!pNext)
121 return 0;
122 if (pNext->IsDictionary())
123 return 1;
124 if (CPDF_Array* pArray = pNext->AsArray())
125 return pArray->GetCount();
126 return 0;
127}
128
129CPDF_Action CPDF_Action::GetSubAction(size_t iIndex) const {
130 if (!m_pDict || !m_pDict->KeyExist("Next"))
Lei Zhang4ecf9a82017-12-11 14:34:58 +0000131 return CPDF_Action(nullptr);
dsinclair02e6f592016-08-02 11:25:48 -0700132
dsinclair38fd8442016-09-15 10:15:32 -0700133 CPDF_Object* pNext = m_pDict->GetDirectObjectFor("Next");
Lei Zhang4ecf9a82017-12-11 14:34:58 +0000134 if (CPDF_Array* pArray = ToArray(pNext))
135 return CPDF_Action(pArray->GetDictAt(iIndex));
dsinclair02e6f592016-08-02 11:25:48 -0700136 if (CPDF_Dictionary* pDict = ToDictionary(pNext)) {
137 if (iIndex == 0)
138 return CPDF_Action(pDict);
dsinclair02e6f592016-08-02 11:25:48 -0700139 }
Lei Zhang4ecf9a82017-12-11 14:34:58 +0000140 return CPDF_Action(nullptr);
dsinclair02e6f592016-08-02 11:25:48 -0700141}