• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "public/fpdf_javascript.h"
6 
7 #include <memory>
8 #include <utility>
9 
10 #include "core/fpdfapi/parser/cpdf_dictionary.h"
11 #include "core/fpdfapi/parser/cpdf_document.h"
12 #include "core/fpdfdoc/cpdf_action.h"
13 #include "core/fpdfdoc/cpdf_nametree.h"
14 #include "core/fxcrt/compiler_specific.h"
15 #include "core/fxcrt/numerics/safe_conversions.h"
16 #include "fpdfsdk/cpdfsdk_helpers.h"
17 
18 struct CPDF_JavaScript {
19   WideString name;
20   WideString script;
21 };
22 
23 FPDF_EXPORT int FPDF_CALLCONV
FPDFDoc_GetJavaScriptActionCount(FPDF_DOCUMENT document)24 FPDFDoc_GetJavaScriptActionCount(FPDF_DOCUMENT document) {
25   CPDF_Document* doc = CPDFDocumentFromFPDFDocument(document);
26   if (!doc)
27     return -1;
28 
29   auto name_tree = CPDF_NameTree::Create(doc, "JavaScript");
30   return name_tree ? pdfium::checked_cast<int>(name_tree->GetCount()) : 0;
31 }
32 
33 FPDF_EXPORT FPDF_JAVASCRIPT_ACTION FPDF_CALLCONV
FPDFDoc_GetJavaScriptAction(FPDF_DOCUMENT document,int index)34 FPDFDoc_GetJavaScriptAction(FPDF_DOCUMENT document, int index) {
35   CPDF_Document* doc = CPDFDocumentFromFPDFDocument(document);
36   if (!doc || index < 0)
37     return nullptr;
38 
39   auto name_tree = CPDF_NameTree::Create(doc, "JavaScript");
40   if (!name_tree || static_cast<size_t>(index) >= name_tree->GetCount())
41     return nullptr;
42 
43   WideString name;
44   RetainPtr<CPDF_Dictionary> obj =
45       ToDictionary(name_tree->LookupValueAndName(index, &name));
46   if (!obj)
47     return nullptr;
48 
49   // Validate |obj|. Type is optional, but must be valid if present.
50   CPDF_Action action(std::move(obj));
51   if (action.GetType() != CPDF_Action::Type::kJavaScript)
52     return nullptr;
53 
54   std::optional<WideString> script = action.MaybeGetJavaScript();
55   if (!script.has_value())
56     return nullptr;
57 
58   auto js = std::make_unique<CPDF_JavaScript>();
59   js->name = name;
60   js->script = script.value();
61   return FPDFJavaScriptActionFromCPDFJavaScriptAction(js.release());
62 }
63 
64 FPDF_EXPORT void FPDF_CALLCONV
FPDFDoc_CloseJavaScriptAction(FPDF_JAVASCRIPT_ACTION javascript)65 FPDFDoc_CloseJavaScriptAction(FPDF_JAVASCRIPT_ACTION javascript) {
66   // Take object back across API and destroy it.
67   std::unique_ptr<CPDF_JavaScript>(
68       CPDFJavaScriptActionFromFPDFJavaScriptAction(javascript));
69 }
70 
71 FPDF_EXPORT unsigned long FPDF_CALLCONV
FPDFJavaScriptAction_GetName(FPDF_JAVASCRIPT_ACTION javascript,FPDF_WCHAR * buffer,unsigned long buflen)72 FPDFJavaScriptAction_GetName(FPDF_JAVASCRIPT_ACTION javascript,
73                              FPDF_WCHAR* buffer,
74                              unsigned long buflen) {
75   CPDF_JavaScript* js =
76       CPDFJavaScriptActionFromFPDFJavaScriptAction(javascript);
77   if (!js) {
78     return 0;
79   }
80   // SAFETY: required from caller.
81   return Utf16EncodeMaybeCopyAndReturnLength(
82       js->name, UNSAFE_BUFFERS(SpanFromFPDFApiArgs(buffer, buflen)));
83 }
84 
85 FPDF_EXPORT unsigned long FPDF_CALLCONV
FPDFJavaScriptAction_GetScript(FPDF_JAVASCRIPT_ACTION javascript,FPDF_WCHAR * buffer,unsigned long buflen)86 FPDFJavaScriptAction_GetScript(FPDF_JAVASCRIPT_ACTION javascript,
87                                FPDF_WCHAR* buffer,
88                                unsigned long buflen) {
89   CPDF_JavaScript* js =
90       CPDFJavaScriptActionFromFPDFJavaScriptAction(javascript);
91   if (!js) {
92     return 0;
93   }
94   // SAFETY: required from caller.
95   return Utf16EncodeMaybeCopyAndReturnLength(
96       js->script, UNSAFE_BUFFERS(SpanFromFPDFApiArgs(buffer, buflen)));
97 }
98