1 // Copyright 2015 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 <math.h>
6
7 #include "core/fxcrt/fx_string.h"
8 #include "fpdfsdk/cpdfsdk_helpers.h"
9 #include "fxjs/cjs_event_context.h"
10 #include "fxjs/cjs_publicmethods.h"
11 #include "testing/external_engine_embedder_test.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "v8/include/v8-container.h"
14 #include "v8/include/v8-context.h"
15 #include "v8/include/v8-isolate.h"
16 #include "v8/include/v8-local-handle.h"
17 #include "v8/include/v8-value.h"
18
19 namespace {
20
RoundDownDate(double date)21 double RoundDownDate(double date) {
22 return date - fmod(date, 86400000);
23 }
24
25 } // namespace
26
27 class CJSPublicMethodsEmbedderTest : public ExternalEngineEmbedderTest {};
28
TEST_F(CJSPublicMethodsEmbedderTest,ParseDateUsingFormat)29 TEST_F(CJSPublicMethodsEmbedderTest, ParseDateUsingFormat) {
30 v8::Isolate::Scope isolate_scope(isolate());
31 v8::HandleScope handle_scope(isolate());
32 v8::Context::Scope context_scope(GetV8Context());
33 bool bWrongFormat;
34 double date;
35
36 // 1968
37 bWrongFormat = false;
38 date = CJS_PublicMethods::ParseDateUsingFormat(isolate(), L"06/25/1968",
39 L"mm/dd/yyyy", &bWrongFormat);
40 date = RoundDownDate(date);
41 EXPECT_DOUBLE_EQ(-47865600000, date);
42 EXPECT_FALSE(bWrongFormat);
43
44 // 1968
45 bWrongFormat = false;
46 date = CJS_PublicMethods::ParseDateUsingFormat(isolate(), L"25061968",
47 L"ddmmyyyy", &bWrongFormat);
48 date = RoundDownDate(date);
49 EXPECT_DOUBLE_EQ(-47865600000, date);
50 EXPECT_FALSE(bWrongFormat);
51
52 // 1968
53 bWrongFormat = false;
54 date = CJS_PublicMethods::ParseDateUsingFormat(isolate(), L"19680625",
55 L"yyyymmdd", &bWrongFormat);
56 date = RoundDownDate(date);
57 EXPECT_DOUBLE_EQ(-47865600000, date);
58 EXPECT_FALSE(bWrongFormat);
59
60 // 1985
61 bWrongFormat = false;
62 date = CJS_PublicMethods::ParseDateUsingFormat(isolate(), L"31121985",
63 L"ddmmyyyy", &bWrongFormat);
64 date = RoundDownDate(date);
65 EXPECT_DOUBLE_EQ(504835200000.0, date);
66 EXPECT_FALSE(bWrongFormat);
67
68 // 2085, the other '85.
69 bWrongFormat = false;
70 date = CJS_PublicMethods::ParseDateUsingFormat(isolate(), L"311285",
71 L"ddmmyy", &bWrongFormat);
72 date = RoundDownDate(date);
73 EXPECT_DOUBLE_EQ(3660595200000.0, date);
74 EXPECT_FALSE(bWrongFormat);
75
76 // 1995
77 bWrongFormat = false;
78 date = CJS_PublicMethods::ParseDateUsingFormat(isolate(), L"01021995",
79 L"ddmmyyyy", &bWrongFormat);
80 date = RoundDownDate(date);
81 EXPECT_DOUBLE_EQ(791596800000.0, date);
82 EXPECT_FALSE(bWrongFormat);
83
84 // 2095, the other '95.
85 bWrongFormat = false;
86 date = CJS_PublicMethods::ParseDateUsingFormat(isolate(), L"010295",
87 L"ddmmyy", &bWrongFormat);
88 date = RoundDownDate(date);
89 EXPECT_DOUBLE_EQ(3947356800000.0, date);
90 EXPECT_FALSE(bWrongFormat);
91
92 // 2005
93 bWrongFormat = false;
94 date = CJS_PublicMethods::ParseDateUsingFormat(isolate(), L"01022005",
95 L"ddmmyyyy", &bWrongFormat);
96 date = RoundDownDate(date);
97 EXPECT_DOUBLE_EQ(1107216000000.0, date);
98 EXPECT_FALSE(bWrongFormat);
99
100 // 2005
101 bWrongFormat = false;
102 date = CJS_PublicMethods::ParseDateUsingFormat(isolate(), L"010205",
103 L"ddmmyy", &bWrongFormat);
104 date = RoundDownDate(date);
105 EXPECT_DOUBLE_EQ(1107216000000.0, date);
106 EXPECT_FALSE(bWrongFormat);
107
108 // 2005 in a different format. https://crbug.com/436572
109 bWrongFormat = false;
110 date = CJS_PublicMethods::ParseDateUsingFormat(isolate(), L"050201",
111 L"yymmdd", &bWrongFormat);
112 date = RoundDownDate(date);
113 EXPECT_DOUBLE_EQ(1107216000000.0, date);
114 EXPECT_FALSE(bWrongFormat);
115 }
116
TEST_F(CJSPublicMethodsEmbedderTest,PrintDateUsingFormat)117 TEST_F(CJSPublicMethodsEmbedderTest, PrintDateUsingFormat) {
118 v8::Isolate::Scope isolate_scope(isolate());
119 v8::HandleScope handle_scope(isolate());
120 v8::Context::Scope context_scope(GetV8Context());
121 WideString formatted_date;
122
123 // 1968-06-25
124 formatted_date =
125 CJS_PublicMethods::PrintDateUsingFormat(-47952000000, L"ddmmyy");
126 EXPECT_EQ(L"250668", formatted_date);
127 formatted_date =
128 CJS_PublicMethods::PrintDateUsingFormat(-47952000000, L"yy/mm/dd");
129 EXPECT_EQ(L"68/06/25", formatted_date);
130
131 // 1969-12-31
132 formatted_date = CJS_PublicMethods::PrintDateUsingFormat(-0.0001, L"ddmmyy");
133 EXPECT_EQ(L"311269", formatted_date);
134 formatted_date = CJS_PublicMethods::PrintDateUsingFormat(-0.0001, L"yy!mmdd");
135 EXPECT_EQ(L"69!1231", formatted_date);
136
137 // 1970-01-01
138 formatted_date = CJS_PublicMethods::PrintDateUsingFormat(0, L"ddmmyy");
139 EXPECT_EQ(L"010170", formatted_date);
140 formatted_date = CJS_PublicMethods::PrintDateUsingFormat(0, L"mm-yyyy-dd");
141 EXPECT_EQ(L"01-1970-01", formatted_date);
142
143 // 1985-12-31
144 formatted_date =
145 CJS_PublicMethods::PrintDateUsingFormat(504835200000.0, L"ddmmyy");
146 EXPECT_EQ(L"311285", formatted_date);
147 formatted_date =
148 CJS_PublicMethods::PrintDateUsingFormat(504835200000.0, L"yymmdd");
149 EXPECT_EQ(L"851231", formatted_date);
150
151 // 1995-02-01
152 formatted_date =
153 CJS_PublicMethods::PrintDateUsingFormat(791596800000.0, L"ddmmyy");
154 EXPECT_EQ(L"010295", formatted_date);
155 formatted_date =
156 CJS_PublicMethods::PrintDateUsingFormat(791596800000.0, L"yyyymmdd");
157 EXPECT_EQ(L"19950201", formatted_date);
158
159 // 2005-02-01
160 formatted_date =
161 CJS_PublicMethods::PrintDateUsingFormat(1107216000000.0, L"ddmmyy");
162 EXPECT_EQ(L"010205", formatted_date);
163 formatted_date =
164 CJS_PublicMethods::PrintDateUsingFormat(1107216000000.0, L"yyyyddmm");
165 EXPECT_EQ(L"20050102", formatted_date);
166
167 // 2085-12-31
168 formatted_date =
169 CJS_PublicMethods::PrintDateUsingFormat(3660595200000.0, L"ddmmyy");
170 EXPECT_EQ(L"311285", formatted_date);
171 formatted_date =
172 CJS_PublicMethods::PrintDateUsingFormat(3660595200000.0, L"yyyydd");
173 EXPECT_EQ(L"208531", formatted_date);
174
175 // 2095-02-01
176 formatted_date =
177 CJS_PublicMethods::PrintDateUsingFormat(3947356800000.0, L"ddmmyy");
178 EXPECT_EQ(L"010295", formatted_date);
179 formatted_date =
180 CJS_PublicMethods::PrintDateUsingFormat(3947356800000.0, L"mmddyyyy");
181 EXPECT_EQ(L"02012095", formatted_date);
182 }
183
TEST_F(CJSPublicMethodsEmbedderTest,AFSimpleCalculateSum)184 TEST_F(CJSPublicMethodsEmbedderTest, AFSimpleCalculateSum) {
185 v8::Isolate::Scope isolate_scope(isolate());
186 v8::HandleScope handle_scope(isolate());
187 v8::Context::Scope context_scope(GetV8Context());
188
189 ASSERT_TRUE(OpenDocument("calculate.pdf"));
190 ScopedEmbedderTestPage page = LoadScopedPage(0);
191 ASSERT_TRUE(page);
192
193 CJS_Runtime runtime(
194 CPDFSDKFormFillEnvironmentFromFPDFFormHandle(form_handle()));
195 runtime.NewEventContext();
196
197 WideString result;
198 runtime.GetCurrentEventContext()->SetValueForTest(&result);
199
200 auto ary = runtime.NewArray();
201 runtime.PutArrayElement(ary, 0, runtime.NewString("Calc1_A"));
202 runtime.PutArrayElement(ary, 1, runtime.NewString("Calc1_B"));
203
204 v8::LocalVector<v8::Value> params(runtime.GetIsolate());
205 params.push_back(runtime.NewString("SUM"));
206 params.push_back(ary);
207
208 CJS_Result ret = CJS_PublicMethods::AFSimple_Calculate(&runtime, params);
209
210 runtime.GetCurrentEventContext()->SetValueForTest(nullptr);
211
212 ASSERT_TRUE(!ret.HasError());
213 ASSERT_TRUE(!ret.HasReturn());
214 ASSERT_EQ(L"7", result);
215 }
216
TEST_F(CJSPublicMethodsEmbedderTest,AFNumberKeystroke)217 TEST_F(CJSPublicMethodsEmbedderTest, AFNumberKeystroke) {
218 v8::Isolate::Scope isolate_scope(isolate());
219 v8::HandleScope handle_scope(isolate());
220 v8::Context::Scope context_scope(GetV8Context());
221
222 ASSERT_TRUE(OpenDocument("calculate.pdf"));
223 ScopedEmbedderTestPage page = LoadScopedPage(0);
224 ASSERT_TRUE(page);
225
226 CJS_Runtime runtime(
227 CPDFSDKFormFillEnvironmentFromFPDFFormHandle(form_handle()));
228 runtime.NewEventContext();
229
230 auto* handler = runtime.GetCurrentEventContext();
231
232 bool valid = true;
233 WideString result = L"-10";
234 WideString change = L"";
235
236 handler->SetValueForTest(&result);
237 handler->SetRCForTest(&valid);
238 handler->SetStrChangeForTest(&change);
239
240 handler->ResetWillCommitForTest();
241 handler->SetSelStart(0);
242 handler->SetSelEnd(0);
243
244 v8::LocalVector<v8::Value> params(runtime.GetIsolate());
245 params.push_back(runtime.NewString("-10"));
246 params.push_back(runtime.NewString(""));
247
248 CJS_Result ret = CJS_PublicMethods::AFNumber_Keystroke(&runtime, params);
249 EXPECT_TRUE(valid);
250 EXPECT_TRUE(!ret.HasError());
251 EXPECT_TRUE(!ret.HasReturn());
252
253
254 // Keep the *SAN bots happy. One of these is an UnownedPtr, another seems to
255 // used during destruction. Clear them all to be safe and consistent.
256 handler->SetValueForTest(nullptr);
257 handler->SetRCForTest(nullptr);
258 handler->SetStrChangeForTest(nullptr);
259 }
260