blob: 0f6826ad9c7e2da368a839639dcc5bb1a9016831 [file] [log] [blame]
Lei Zhang25661d12019-08-01 21:57:23 +00001// Copyright 2019 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#include "public/fpdf_javascript.h"
6
7#include <memory>
8
9#include "core/fpdfapi/parser/cpdf_dictionary.h"
10#include "core/fpdfapi/parser/cpdf_document.h"
11#include "core/fpdfdoc/cpdf_action.h"
12#include "core/fpdfdoc/cpdf_nametree.h"
13#include "fpdfsdk/cpdfsdk_helpers.h"
Tom Sepez5ea5fa92022-03-08 00:15:23 +000014#include "third_party/base/numerics/safe_conversions.h"
Lei Zhang25661d12019-08-01 21:57:23 +000015
16struct CPDF_JavaScript {
17 WideString name;
18 WideString script;
19};
20
21FPDF_EXPORT int FPDF_CALLCONV
22FPDFDoc_GetJavaScriptActionCount(FPDF_DOCUMENT document) {
23 CPDF_Document* doc = CPDFDocumentFromFPDFDocument(document);
Lei Zhang1575b472020-04-02 23:09:15 +000024 if (!doc)
25 return -1;
26
27 auto name_tree = CPDF_NameTree::Create(doc, "JavaScript");
Tom Sepez5ea5fa92022-03-08 00:15:23 +000028 return name_tree ? pdfium::base::checked_cast<int>(name_tree->GetCount()) : 0;
Lei Zhang25661d12019-08-01 21:57:23 +000029}
30
31FPDF_EXPORT FPDF_JAVASCRIPT_ACTION FPDF_CALLCONV
32FPDFDoc_GetJavaScriptAction(FPDF_DOCUMENT document, int index) {
33 CPDF_Document* doc = CPDFDocumentFromFPDFDocument(document);
34 if (!doc || index < 0)
35 return nullptr;
36
Lei Zhang1575b472020-04-02 23:09:15 +000037 auto name_tree = CPDF_NameTree::Create(doc, "JavaScript");
38 if (!name_tree || static_cast<size_t>(index) >= name_tree->GetCount())
Lei Zhang25661d12019-08-01 21:57:23 +000039 return nullptr;
40
41 WideString name;
42 CPDF_Dictionary* obj =
Lei Zhang1575b472020-04-02 23:09:15 +000043 ToDictionary(name_tree->LookupValueAndName(index, &name));
Lei Zhang25661d12019-08-01 21:57:23 +000044 if (!obj)
45 return nullptr;
46
47 // Validate |obj|. Type is optional, but must be valid if present.
48 CPDF_Action action(obj);
Lei Zhang7f195a12021-04-13 18:56:36 +000049 if (action.GetType() != CPDF_Action::Type::kJavaScript)
Lei Zhang25661d12019-08-01 21:57:23 +000050 return nullptr;
51
Lei Zhang2c495302021-10-07 23:13:30 +000052 absl::optional<WideString> script = action.MaybeGetJavaScript();
Lei Zhang25661d12019-08-01 21:57:23 +000053 if (!script.has_value())
54 return nullptr;
55
Tom Sepez5af95432020-05-15 22:55:16 +000056 auto js = std::make_unique<CPDF_JavaScript>();
Lei Zhang25661d12019-08-01 21:57:23 +000057 js->name = name;
58 js->script = script.value();
59 return FPDFJavaScriptActionFromCPDFJavaScriptAction(js.release());
60}
61
62FPDF_EXPORT void FPDF_CALLCONV
63FPDFDoc_CloseJavaScriptAction(FPDF_JAVASCRIPT_ACTION javascript) {
64 // Take object back across API and destroy it.
65 std::unique_ptr<CPDF_JavaScript>(
66 CPDFJavaScriptActionFromFPDFJavaScriptAction(javascript));
67}
68
69FPDF_EXPORT unsigned long FPDF_CALLCONV
70FPDFJavaScriptAction_GetName(FPDF_JAVASCRIPT_ACTION javascript,
71 FPDF_WCHAR* buffer,
72 unsigned long buflen) {
73 CPDF_JavaScript* js =
74 CPDFJavaScriptActionFromFPDFJavaScriptAction(javascript);
75 if (!js)
76 return 0;
77 return Utf16EncodeMaybeCopyAndReturnLength(js->name, buffer, buflen);
78}
79
80FPDF_EXPORT unsigned long FPDF_CALLCONV
81FPDFJavaScriptAction_GetScript(FPDF_JAVASCRIPT_ACTION javascript,
82 FPDF_WCHAR* buffer,
83 unsigned long buflen) {
84 CPDF_JavaScript* js =
85 CPDFJavaScriptActionFromFPDFJavaScriptAction(javascript);
86 if (!js)
87 return 0;
88 return Utf16EncodeMaybeCopyAndReturnLength(js->script, buffer, buflen);
89}