xref: /aosp_15_r20/external/pdfium/testing/xfa_js_embedder_test.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright 2017 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 "testing/xfa_js_embedder_test.h"
6 
7 #include <memory>
8 #include <string>
9 
10 #include "fpdfsdk/cpdfsdk_helpers.h"
11 #include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
12 #include "fxjs/fxv8.h"
13 #include "fxjs/xfa/cfxjse_engine.h"
14 #include "fxjs/xfa/cfxjse_isolatetracker.h"
15 #include "fxjs/xfa/cfxjse_value.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "third_party/base/check_op.h"
18 #include "v8/include/v8-container.h"
19 #include "v8/include/v8-local-handle.h"
20 #include "v8/include/v8-value.h"
21 
22 XFAJSEmbedderTest::XFAJSEmbedderTest() = default;
23 
24 XFAJSEmbedderTest::~XFAJSEmbedderTest() = default;
25 
SetUp()26 void XFAJSEmbedderTest::SetUp() {
27   JSEmbedderTest::SetUp();
28 }
29 
TearDown()30 void XFAJSEmbedderTest::TearDown() {
31   value_.Reset();
32   script_context_ = nullptr;
33 
34   JSEmbedderTest::TearDown();
35 }
36 
GetXFADocument() const37 CXFA_Document* XFAJSEmbedderTest::GetXFADocument() const {
38   auto* pDoc = CPDFDocumentFromFPDFDocument(document());
39   if (!pDoc)
40     return nullptr;
41 
42   auto* pContext = static_cast<CPDFXFA_Context*>(pDoc->GetExtension());
43   if (!pContext)
44     return nullptr;
45 
46   CXFA_FFDoc* pFFDoc = pContext->GetXFADoc();
47   if (!pFFDoc)
48     return nullptr;
49 
50   return pFFDoc->GetXFADoc();
51 }
52 
GetValue() const53 v8::Local<v8::Value> XFAJSEmbedderTest::GetValue() const {
54   return v8::Local<v8::Value>::New(isolate(), value_);
55 }
56 
OpenDocumentWithOptions(const std::string & filename,const char * password,LinearizeOption linearize_option,JavaScriptOption javascript_option)57 bool XFAJSEmbedderTest::OpenDocumentWithOptions(
58     const std::string& filename,
59     const char* password,
60     LinearizeOption linearize_option,
61     JavaScriptOption javascript_option) {
62   // JS required for XFA.
63   DCHECK_EQ(javascript_option, JavaScriptOption::kEnableJavaScript);
64   if (!EmbedderTest::OpenDocumentWithOptions(
65           filename, password, linearize_option, javascript_option)) {
66     return false;
67   }
68   CXFA_Document* pDoc = GetXFADocument();
69   if (!pDoc)
70     return false;
71 
72   script_context_ = pDoc->GetScriptContext();
73   return true;
74 }
75 
Execute(ByteStringView input)76 bool XFAJSEmbedderTest::Execute(ByteStringView input) {
77   CFXJSE_ScopeUtil_IsolateHandleContext scope(
78       script_context_->GetJseContextForTest());
79   if (ExecuteHelper(input))
80     return true;
81 
82   fprintf(stderr, "FormCalc: %.*s\n", static_cast<int>(input.GetLength()),
83           input.unterminated_c_str());
84 
85   v8::Local<v8::Value> result = GetValue();
86   if (!fxv8::IsArray(result))
87     return false;
88 
89   v8::Local<v8::Value> msg = fxv8::ReentrantGetArrayElementHelper(
90       isolate(), result.As<v8::Array>(), 1);
91   if (!fxv8::IsString(msg))
92     return false;
93 
94   WideString str = fxv8::ReentrantToWideStringHelper(isolate(), msg);
95   if (!str.IsEmpty())
96     fprintf(stderr, "JS ERROR: %ls\n", str.c_str());
97   return false;
98 }
99 
ExecuteSilenceFailure(ByteStringView input)100 bool XFAJSEmbedderTest::ExecuteSilenceFailure(ByteStringView input) {
101   CFXJSE_ScopeUtil_IsolateHandleContext scope(
102       script_context_->GetJseContextForTest());
103   return ExecuteHelper(input);
104 }
105 
ExecuteHelper(ByteStringView input)106 bool XFAJSEmbedderTest::ExecuteHelper(ByteStringView input) {
107   auto value = std::make_unique<CFXJSE_Value>();
108   bool ret = script_context_->RunScript(
109       CXFA_Script::Type::Formcalc, WideString::FromUTF8(input).AsStringView(),
110       value.get(), GetXFADocument()->GetRoot());
111   value_.Reset(isolate(), value->GetValue(isolate()));
112   return ret;
113 }
114