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