xref: /aosp_15_r20/external/pdfium/fpdfsdk/fpdf_javascript.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
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 "fpdfsdk/cpdfsdk_helpers.h"
15 #include "third_party/base/numerics/safe_conversions.h"
16 
17 struct CPDF_JavaScript {
18   WideString name;
19   WideString script;
20 };
21 
22 FPDF_EXPORT int FPDF_CALLCONV
FPDFDoc_GetJavaScriptActionCount(FPDF_DOCUMENT document)23 FPDFDoc_GetJavaScriptActionCount(FPDF_DOCUMENT document) {
24   CPDF_Document* doc = CPDFDocumentFromFPDFDocument(document);
25   if (!doc)
26     return -1;
27 
28   auto name_tree = CPDF_NameTree::Create(doc, "JavaScript");
29   return name_tree ? pdfium::base::checked_cast<int>(name_tree->GetCount()) : 0;
30 }
31 
32 FPDF_EXPORT FPDF_JAVASCRIPT_ACTION FPDF_CALLCONV
FPDFDoc_GetJavaScriptAction(FPDF_DOCUMENT document,int index)33 FPDFDoc_GetJavaScriptAction(FPDF_DOCUMENT document, int index) {
34   CPDF_Document* doc = CPDFDocumentFromFPDFDocument(document);
35   if (!doc || index < 0)
36     return nullptr;
37 
38   auto name_tree = CPDF_NameTree::Create(doc, "JavaScript");
39   if (!name_tree || static_cast<size_t>(index) >= name_tree->GetCount())
40     return nullptr;
41 
42   WideString name;
43   RetainPtr<CPDF_Dictionary> obj =
44       ToDictionary(name_tree->LookupValueAndName(index, &name));
45   if (!obj)
46     return nullptr;
47 
48   // Validate |obj|. Type is optional, but must be valid if present.
49   CPDF_Action action(std::move(obj));
50   if (action.GetType() != CPDF_Action::Type::kJavaScript)
51     return nullptr;
52 
53   absl::optional<WideString> script = action.MaybeGetJavaScript();
54   if (!script.has_value())
55     return nullptr;
56 
57   auto js = std::make_unique<CPDF_JavaScript>();
58   js->name = name;
59   js->script = script.value();
60   return FPDFJavaScriptActionFromCPDFJavaScriptAction(js.release());
61 }
62 
63 FPDF_EXPORT void FPDF_CALLCONV
FPDFDoc_CloseJavaScriptAction(FPDF_JAVASCRIPT_ACTION javascript)64 FPDFDoc_CloseJavaScriptAction(FPDF_JAVASCRIPT_ACTION javascript) {
65   // Take object back across API and destroy it.
66   std::unique_ptr<CPDF_JavaScript>(
67       CPDFJavaScriptActionFromFPDFJavaScriptAction(javascript));
68 }
69 
70 FPDF_EXPORT unsigned long FPDF_CALLCONV
FPDFJavaScriptAction_GetName(FPDF_JAVASCRIPT_ACTION javascript,FPDF_WCHAR * buffer,unsigned long buflen)71 FPDFJavaScriptAction_GetName(FPDF_JAVASCRIPT_ACTION javascript,
72                              FPDF_WCHAR* buffer,
73                              unsigned long buflen) {
74   CPDF_JavaScript* js =
75       CPDFJavaScriptActionFromFPDFJavaScriptAction(javascript);
76   if (!js)
77     return 0;
78   return Utf16EncodeMaybeCopyAndReturnLength(js->name, buffer, buflen);
79 }
80 
81 FPDF_EXPORT unsigned long FPDF_CALLCONV
FPDFJavaScriptAction_GetScript(FPDF_JAVASCRIPT_ACTION javascript,FPDF_WCHAR * buffer,unsigned long buflen)82 FPDFJavaScriptAction_GetScript(FPDF_JAVASCRIPT_ACTION javascript,
83                                FPDF_WCHAR* buffer,
84                                unsigned long buflen) {
85   CPDF_JavaScript* js =
86       CPDFJavaScriptActionFromFPDFJavaScriptAction(javascript);
87   if (!js)
88     return 0;
89   return Utf16EncodeMaybeCopyAndReturnLength(js->script, buffer, buflen);
90 }
91