• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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