blob: 1a27d222700bd129547fe7e2a46e7ec91a18256a [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// Copyright 2014 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.
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
Dan Sinclairf766ad22016-03-14 13:51:24 -04007#include "fpdfsdk/javascript/JS_Value.h"
Tom Sepez37458412015-10-06 11:33:46 -07008
Tom Sepez39bfe122015-09-17 15:25:23 -07009#include <time.h>
Dan Sinclair3ebd1212016-03-09 09:59:23 -050010
Tom Sepezbd932572016-01-29 09:10:41 -080011#include <algorithm>
Tom Sepez39bfe122015-09-17 15:25:23 -070012#include <cmath>
13#include <limits>
Dan Sinclair3ebd1212016-03-09 09:59:23 -050014#include <vector>
Tom Sepez39bfe122015-09-17 15:25:23 -070015
Dan Sinclairf766ad22016-03-14 13:51:24 -040016#include "fpdfsdk/javascript/Document.h"
17#include "fpdfsdk/javascript/JS_Define.h"
18#include "fpdfsdk/javascript/JS_Object.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070019
tsepezfbf52c22016-07-25 11:17:07 -070020namespace {
21
tsepezfbf52c22016-07-25 11:17:07 -070022double
23MakeDate(int year, int mon, int day, int hour, int min, int sec, int ms) {
24 return JS_MakeDate(JS_MakeDay(year, mon, day),
25 JS_MakeTime(hour, min, sec, ms));
26}
27
Lei Zhangab5939e2017-06-16 02:23:18 -070028double GetLocalTZA() {
29 if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
30 return 0;
31 time_t t = 0;
32 time(&t);
33 localtime(&t);
Tom Sepezbd456562017-08-04 14:45:14 -070034#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
Tom Sepeza2da7c52017-08-03 13:34:08 -070035 // In gcc 'timezone' is a global variable declared in time.h. In VC++, that
36 // variable was removed in VC++ 2015, with _get_timezone replacing it.
Lei Zhangab5939e2017-06-16 02:23:18 -070037 long timezone = 0;
38 _get_timezone(&timezone);
Tom Sepezbd456562017-08-04 14:45:14 -070039#endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
Lei Zhangab5939e2017-06-16 02:23:18 -070040 return (double)(-(timezone * 1000));
41}
42
43int GetDaylightSavingTA(double d) {
44 if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
45 return 0;
46 time_t t = (time_t)(d / 1000);
47 struct tm* tmp = localtime(&t);
48 if (!tmp)
49 return 0;
50 if (tmp->tm_isdst > 0)
51 // One hour.
52 return (int)60 * 60 * 1000;
53 return 0;
54}
55
56double Mod(double x, double y) {
57 double r = fmod(x, y);
58 if (r < 0)
59 r += y;
60 return r;
61}
62
Lei Zhangab5939e2017-06-16 02:23:18 -070063bool IsLeapYear(int year) {
64 return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 != 0));
65}
66
67int DayFromYear(int y) {
68 return (int)(365 * (y - 1970.0) + floor((y - 1969.0) / 4) -
69 floor((y - 1901.0) / 100) + floor((y - 1601.0) / 400));
70}
71
72double TimeFromYear(int y) {
73 return 86400000.0 * DayFromYear(y);
74}
75
76static const uint16_t daysMonth[12] = {0, 31, 59, 90, 120, 151,
77 181, 212, 243, 273, 304, 334};
78static const uint16_t leapDaysMonth[12] = {0, 31, 60, 91, 121, 152,
79 182, 213, 244, 274, 305, 335};
80
81double TimeFromYearMonth(int y, int m) {
82 const uint16_t* pMonth = IsLeapYear(y) ? leapDaysMonth : daysMonth;
83 return TimeFromYear(y) + ((double)pMonth[m]) * 86400000;
84}
85
86int Day(double t) {
Tom Sepezdf950b82017-08-04 11:33:49 -070087 return static_cast<int>(floor(t / 86400000.0));
Lei Zhangab5939e2017-06-16 02:23:18 -070088}
89
90int YearFromTime(double t) {
91 // estimate the time.
Tom Sepezdf950b82017-08-04 11:33:49 -070092 int y = 1970 + static_cast<int>(t / (365.2425 * 86400000.0));
Lei Zhangab5939e2017-06-16 02:23:18 -070093 if (TimeFromYear(y) <= t) {
94 while (TimeFromYear(y + 1) <= t)
95 y++;
96 } else {
97 while (TimeFromYear(y) > t)
98 y--;
99 }
100 return y;
101}
102
103int DayWithinYear(double t) {
104 int year = YearFromTime(t);
105 int day = Day(t);
106 return day - DayFromYear(year);
107}
108
109int MonthFromTime(double t) {
110 int day = DayWithinYear(t);
111 int year = YearFromTime(t);
112 if (0 <= day && day < 31)
113 return 0;
114 if (31 <= day && day < 59 + IsLeapYear(year))
115 return 1;
116 if ((59 + IsLeapYear(year)) <= day && day < (90 + IsLeapYear(year)))
117 return 2;
118 if ((90 + IsLeapYear(year)) <= day && day < (120 + IsLeapYear(year)))
119 return 3;
120 if ((120 + IsLeapYear(year)) <= day && day < (151 + IsLeapYear(year)))
121 return 4;
122 if ((151 + IsLeapYear(year)) <= day && day < (181 + IsLeapYear(year)))
123 return 5;
124 if ((181 + IsLeapYear(year)) <= day && day < (212 + IsLeapYear(year)))
125 return 6;
126 if ((212 + IsLeapYear(year)) <= day && day < (243 + IsLeapYear(year)))
127 return 7;
128 if ((243 + IsLeapYear(year)) <= day && day < (273 + IsLeapYear(year)))
129 return 8;
130 if ((273 + IsLeapYear(year)) <= day && day < (304 + IsLeapYear(year)))
131 return 9;
132 if ((304 + IsLeapYear(year)) <= day && day < (334 + IsLeapYear(year)))
133 return 10;
134 if ((334 + IsLeapYear(year)) <= day && day < (365 + IsLeapYear(year)))
135 return 11;
136
137 return -1;
138}
139
140int DateFromTime(double t) {
141 int day = DayWithinYear(t);
142 int year = YearFromTime(t);
143 int leap = IsLeapYear(year);
144 int month = MonthFromTime(t);
145 switch (month) {
146 case 0:
147 return day + 1;
148 case 1:
149 return day - 30;
150 case 2:
151 return day - 58 - leap;
152 case 3:
153 return day - 89 - leap;
154 case 4:
155 return day - 119 - leap;
156 case 5:
157 return day - 150 - leap;
158 case 6:
159 return day - 180 - leap;
160 case 7:
161 return day - 211 - leap;
162 case 8:
163 return day - 242 - leap;
164 case 9:
165 return day - 272 - leap;
166 case 10:
167 return day - 303 - leap;
168 case 11:
169 return day - 333 - leap;
170 default:
171 return 0;
172 }
173}
174
tsepezfbf52c22016-07-25 11:17:07 -0700175} // namespace
176
tsepezf3dc8c62016-08-10 06:29:29 -0700177CJS_Value::CJS_Value(CJS_Runtime* pRuntime) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700178
tsepez40faa792016-07-15 17:58:02 -0700179CJS_Value::CJS_Value(CJS_Runtime* pRuntime, v8::Local<v8::Value> pValue)
tsepezf3dc8c62016-08-10 06:29:29 -0700180 : m_pValue(pValue) {}
Tom Sepez67fd5df2015-10-08 12:24:19 -0700181
182CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const int& iValue)
tsepezb4694242016-08-15 16:44:55 -0700183 : m_pValue(pRuntime->NewNumber(iValue)) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700184
Tom Sepez67fd5df2015-10-08 12:24:19 -0700185CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const bool& bValue)
tsepezb4694242016-08-15 16:44:55 -0700186 : m_pValue(pRuntime->NewBoolean(bValue)) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700187
Tom Sepez67fd5df2015-10-08 12:24:19 -0700188CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const float& fValue)
tsepezb4694242016-08-15 16:44:55 -0700189 : m_pValue(pRuntime->NewNumber(fValue)) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700190
Tom Sepez67fd5df2015-10-08 12:24:19 -0700191CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const double& dValue)
tsepezb4694242016-08-15 16:44:55 -0700192 : m_pValue(pRuntime->NewNumber(dValue)) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700193
tsepezf3dc8c62016-08-10 06:29:29 -0700194CJS_Value::CJS_Value(CJS_Runtime* pRuntime, CJS_Object* pObj) {
195 if (pObj)
196 m_pValue = pObj->ToV8Object();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700197}
198
Dan Sinclair812e96c2017-03-13 16:43:37 -0400199CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const wchar_t* pWstr)
tsepezb4694242016-08-15 16:44:55 -0700200 : m_pValue(pRuntime->NewString(pWstr)) {}
Tom Sepezf79a69c2014-10-30 13:23:42 -0700201
Dan Sinclair812e96c2017-03-13 16:43:37 -0400202CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const char* pStr)
Ryan Harrison275e2602017-09-18 14:23:18 -0400203 : m_pValue(pRuntime->NewString(WideString::FromLocal(pStr).c_str())) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700204
tsepeze5aff742016-08-08 09:49:42 -0700205CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const CJS_Array& array)
tsepezb4694242016-08-15 16:44:55 -0700206 : m_pValue(array.ToV8Array(pRuntime)) {}
tsepezf3dc8c62016-08-10 06:29:29 -0700207
208CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const CJS_Date& date)
tsepezb4694242016-08-15 16:44:55 -0700209 : m_pValue(date.ToV8Date(pRuntime)) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700210
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700211CJS_Value::~CJS_Value() {}
212
weili625ad662016-06-15 11:21:33 -0700213CJS_Value::CJS_Value(const CJS_Value& other) = default;
214
tsepez40faa792016-07-15 17:58:02 -0700215void CJS_Value::Attach(v8::Local<v8::Value> pValue) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700216 m_pValue = pValue;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700217}
218
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700219void CJS_Value::Detach() {
220 m_pValue = v8::Local<v8::Value>();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700221}
222
tsepezb4694242016-08-15 16:44:55 -0700223int CJS_Value::ToInt(CJS_Runtime* pRuntime) const {
224 return pRuntime->ToInt32(m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700225}
226
tsepezb4694242016-08-15 16:44:55 -0700227bool CJS_Value::ToBool(CJS_Runtime* pRuntime) const {
228 return pRuntime->ToBoolean(m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700229}
230
tsepezb4694242016-08-15 16:44:55 -0700231double CJS_Value::ToDouble(CJS_Runtime* pRuntime) const {
tsepeze6cf0132017-01-18 14:38:18 -0800232 return pRuntime->ToDouble(m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700233}
234
tsepezb4694242016-08-15 16:44:55 -0700235float CJS_Value::ToFloat(CJS_Runtime* pRuntime) const {
236 return (float)ToDouble(pRuntime);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700237}
238
tsepezb4694242016-08-15 16:44:55 -0700239CJS_Object* CJS_Value::ToCJSObject(CJS_Runtime* pRuntime) const {
240 v8::Local<v8::Object> pObj = pRuntime->ToObject(m_pValue);
241 return static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(pObj));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700242}
243
tsepezb4694242016-08-15 16:44:55 -0700244v8::Local<v8::Object> CJS_Value::ToV8Object(CJS_Runtime* pRuntime) const {
245 return pRuntime->ToObject(m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700246}
247
Ryan Harrison275e2602017-09-18 14:23:18 -0400248WideString CJS_Value::ToCFXWideString(CJS_Runtime* pRuntime) const {
tsepeze6cf0132017-01-18 14:38:18 -0800249 return pRuntime->ToWideString(m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700250}
251
Ryan Harrison275e2602017-09-18 14:23:18 -0400252ByteString CJS_Value::ToCFXByteString(CJS_Runtime* pRuntime) const {
253 return ByteString::FromUnicode(ToCFXWideString(pRuntime));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700254}
255
tsepezb4694242016-08-15 16:44:55 -0700256v8::Local<v8::Value> CJS_Value::ToV8Value(CJS_Runtime* pRuntime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700257 return m_pValue;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700258}
259
tsepezb4694242016-08-15 16:44:55 -0700260v8::Local<v8::Array> CJS_Value::ToV8Array(CJS_Runtime* pRuntime) const {
tsepeze6cf0132017-01-18 14:38:18 -0800261 return pRuntime->ToArray(m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700262}
263
tsepezf3dc8c62016-08-10 06:29:29 -0700264void CJS_Value::SetNull(CJS_Runtime* pRuntime) {
tsepezb4694242016-08-15 16:44:55 -0700265 m_pValue = pRuntime->NewNull();
tsepezf3dc8c62016-08-10 06:29:29 -0700266}
267
tsepezb4694242016-08-15 16:44:55 -0700268void CJS_Value::MaybeCoerceToNumber(CJS_Runtime* pRuntime) {
Tom Sepez4246b002016-01-20 11:48:29 -0800269 bool bAllowNaN = false;
tsepez40faa792016-07-15 17:58:02 -0700270 if (GetType() == VT_string) {
Ryan Harrison275e2602017-09-18 14:23:18 -0400271 ByteString bstr = ToCFXByteString(pRuntime);
Tom Sepez4246b002016-01-20 11:48:29 -0800272 if (bstr.GetLength() == 0)
273 return;
274 if (bstr == "NaN")
275 bAllowNaN = true;
276 }
tsepezb4694242016-08-15 16:44:55 -0700277 v8::Isolate* pIsolate = pRuntime->GetIsolate();
tsepezf3dc8c62016-08-10 06:29:29 -0700278 v8::TryCatch try_catch(pIsolate);
Tom Sepez4246b002016-01-20 11:48:29 -0800279 v8::MaybeLocal<v8::Number> maybeNum =
tsepezf3dc8c62016-08-10 06:29:29 -0700280 m_pValue->ToNumber(pIsolate->GetCurrentContext());
Tom Sepez4246b002016-01-20 11:48:29 -0800281 if (maybeNum.IsEmpty())
282 return;
283 v8::Local<v8::Number> num = maybeNum.ToLocalChecked();
284 if (std::isnan(num->Value()) && !bAllowNaN)
285 return;
286 m_pValue = num;
Tom Sepez4246b002016-01-20 11:48:29 -0800287}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700288
tsepez40faa792016-07-15 17:58:02 -0700289// static
290CJS_Value::Type CJS_Value::GetValueType(v8::Local<v8::Value> value) {
291 if (value.IsEmpty())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700292 return VT_unknown;
tsepez40faa792016-07-15 17:58:02 -0700293 if (value->IsString())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700294 return VT_string;
tsepez40faa792016-07-15 17:58:02 -0700295 if (value->IsNumber())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700296 return VT_number;
tsepez40faa792016-07-15 17:58:02 -0700297 if (value->IsBoolean())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700298 return VT_boolean;
tsepez40faa792016-07-15 17:58:02 -0700299 if (value->IsDate())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700300 return VT_date;
tsepez40faa792016-07-15 17:58:02 -0700301 if (value->IsObject())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700302 return VT_object;
tsepez40faa792016-07-15 17:58:02 -0700303 if (value->IsNull())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700304 return VT_null;
tsepez40faa792016-07-15 17:58:02 -0700305 if (value->IsUndefined())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700306 return VT_undefined;
307 return VT_unknown;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700308}
309
tsepezf3dc8c62016-08-10 06:29:29 -0700310bool CJS_Value::IsArrayObject() const {
311 return !m_pValue.IsEmpty() && m_pValue->IsArray();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700312}
313
tsepezf3dc8c62016-08-10 06:29:29 -0700314bool CJS_Value::IsDateObject() const {
315 return !m_pValue.IsEmpty() && m_pValue->IsDate();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700316}
317
tsepezb4694242016-08-15 16:44:55 -0700318bool CJS_Value::ConvertToArray(CJS_Runtime* pRuntime, CJS_Array& array) const {
tsepezf3dc8c62016-08-10 06:29:29 -0700319 if (!IsArrayObject())
320 return false;
tsepezb4694242016-08-15 16:44:55 -0700321 array.Attach(pRuntime->ToArray(m_pValue));
tsepezf3dc8c62016-08-10 06:29:29 -0700322 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700323}
324
tsepezb4694242016-08-15 16:44:55 -0700325bool CJS_Value::ConvertToDate(CJS_Runtime* pRuntime, CJS_Date& date) const {
tsepezf3dc8c62016-08-10 06:29:29 -0700326 if (!IsDateObject())
327 return false;
328 v8::Local<v8::Value> mutable_value = m_pValue;
329 date.Attach(mutable_value.As<v8::Date>());
330 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700331}
332
Tom Sepez67fd5df2015-10-08 12:24:19 -0700333CJS_PropValue::CJS_PropValue(CJS_Runtime* pRuntime)
tsepezf3dc8c62016-08-10 06:29:29 -0700334 : m_bIsSetting(0), m_Value(pRuntime), m_pJSRuntime(pRuntime) {}
335
336CJS_PropValue::CJS_PropValue(CJS_Runtime* pRuntime, const CJS_Value& value)
337 : m_bIsSetting(0), m_Value(value), m_pJSRuntime(pRuntime) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700338
Dan Sinclairf766ad22016-03-14 13:51:24 -0400339CJS_PropValue::~CJS_PropValue() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700340
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700341void CJS_PropValue::operator<<(int iValue) {
342 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700343 m_Value = CJS_Value(m_pJSRuntime.Get(), iValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700344}
345
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700346void CJS_PropValue::operator>>(int& iValue) const {
347 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700348 iValue = m_Value.ToInt(m_pJSRuntime.Get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700349}
350
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700351void CJS_PropValue::operator<<(bool bValue) {
352 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700353 m_Value = CJS_Value(m_pJSRuntime.Get(), bValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700354}
355
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700356void CJS_PropValue::operator>>(bool& bValue) const {
357 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700358 bValue = m_Value.ToBool(m_pJSRuntime.Get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700359}
360
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700361void CJS_PropValue::operator<<(double dValue) {
362 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700363 m_Value = CJS_Value(m_pJSRuntime.Get(), dValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700364}
365
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700366void CJS_PropValue::operator>>(double& dValue) const {
367 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700368 dValue = m_Value.ToDouble(m_pJSRuntime.Get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700369}
370
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700371void CJS_PropValue::operator<<(CJS_Object* pObj) {
372 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700373 m_Value = CJS_Value(m_pJSRuntime.Get(), pObj);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700374}
375
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700376void CJS_PropValue::operator>>(CJS_Object*& ppObj) const {
377 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700378 ppObj = m_Value.ToCJSObject(m_pJSRuntime.Get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700379}
380
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700381void CJS_PropValue::operator<<(CJS_Document* pJsDoc) {
382 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700383 m_Value = CJS_Value(m_pJSRuntime.Get(), pJsDoc);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700384}
385
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700386void CJS_PropValue::operator>>(CJS_Document*& ppJsDoc) const {
387 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700388 ppJsDoc = static_cast<CJS_Document*>(m_Value.ToCJSObject(m_pJSRuntime.Get()));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700389}
390
Tom Sepez808a99e2015-09-10 12:28:37 -0700391void CJS_PropValue::operator<<(v8::Local<v8::Object> pObj) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700392 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700393 m_Value = CJS_Value(m_pJSRuntime.Get(), pObj);
JUN FANG33f6f0d2015-04-06 12:39:51 -0700394}
395
Tom Sepez808a99e2015-09-10 12:28:37 -0700396void CJS_PropValue::operator>>(v8::Local<v8::Object>& ppObj) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700397 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700398 ppObj = m_Value.ToV8Object(m_pJSRuntime.Get());
JUN FANG33f6f0d2015-04-06 12:39:51 -0700399}
400
Ryan Harrison275e2602017-09-18 14:23:18 -0400401void CJS_PropValue::operator<<(ByteString str) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700402 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700403 m_Value = CJS_Value(m_pJSRuntime.Get(), str.c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700404}
405
Ryan Harrison275e2602017-09-18 14:23:18 -0400406void CJS_PropValue::operator>>(ByteString& str) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700407 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700408 str = m_Value.ToCFXByteString(m_pJSRuntime.Get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700409}
410
Dan Sinclair812e96c2017-03-13 16:43:37 -0400411void CJS_PropValue::operator<<(const wchar_t* str) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700412 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700413 m_Value = CJS_Value(m_pJSRuntime.Get(), str);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700414}
415
Ryan Harrison275e2602017-09-18 14:23:18 -0400416void CJS_PropValue::operator>>(WideString& wide_string) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700417 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700418 wide_string = m_Value.ToCFXWideString(m_pJSRuntime.Get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700419}
420
Ryan Harrison275e2602017-09-18 14:23:18 -0400421void CJS_PropValue::operator<<(WideString wide_string) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700422 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700423 m_Value = CJS_Value(m_pJSRuntime.Get(), wide_string.c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700424}
425
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700426void CJS_PropValue::operator>>(CJS_Array& array) const {
427 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700428 m_Value.ConvertToArray(m_pJSRuntime.Get(), array);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700429}
430
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700431void CJS_PropValue::operator<<(CJS_Array& array) {
432 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700433 m_Value = CJS_Value(m_pJSRuntime.Get(), array.ToV8Array(m_pJSRuntime.Get()));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700434}
435
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700436void CJS_PropValue::operator>>(CJS_Date& date) const {
437 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700438 m_Value.ConvertToDate(m_pJSRuntime.Get(), date);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700439}
440
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700441void CJS_PropValue::operator<<(CJS_Date& date) {
442 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700443 m_Value = CJS_Value(m_pJSRuntime.Get(), date);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700444}
445
tsepeze5aff742016-08-08 09:49:42 -0700446CJS_Array::CJS_Array() {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700447
weili625ad662016-06-15 11:21:33 -0700448CJS_Array::CJS_Array(const CJS_Array& other) = default;
449
tsepeze5aff742016-08-08 09:49:42 -0700450CJS_Array::~CJS_Array() {}
451
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700452void CJS_Array::Attach(v8::Local<v8::Array> pArray) {
453 m_pArray = pArray;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700454}
455
tsepezb4694242016-08-15 16:44:55 -0700456void CJS_Array::GetElement(CJS_Runtime* pRuntime,
tsepeze5aff742016-08-08 09:49:42 -0700457 unsigned index,
458 CJS_Value& value) const {
459 if (!m_pArray.IsEmpty())
tsepezb4694242016-08-15 16:44:55 -0700460 value.Attach(pRuntime->GetArrayElement(m_pArray, index));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700461}
462
tsepezb4694242016-08-15 16:44:55 -0700463void CJS_Array::SetElement(CJS_Runtime* pRuntime,
tsepeze5aff742016-08-08 09:49:42 -0700464 unsigned index,
465 const CJS_Value& value) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700466 if (m_pArray.IsEmpty())
tsepezb4694242016-08-15 16:44:55 -0700467 m_pArray = pRuntime->NewArray();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700468
tsepezb4694242016-08-15 16:44:55 -0700469 pRuntime->PutArrayElement(m_pArray, index, value.ToV8Value(pRuntime));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700470}
471
tsepezb4694242016-08-15 16:44:55 -0700472int CJS_Array::GetLength(CJS_Runtime* pRuntime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700473 if (m_pArray.IsEmpty())
474 return 0;
tsepezb4694242016-08-15 16:44:55 -0700475 return pRuntime->GetArrayLength(m_pArray);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700476}
477
tsepezb4694242016-08-15 16:44:55 -0700478v8::Local<v8::Array> CJS_Array::ToV8Array(CJS_Runtime* pRuntime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700479 if (m_pArray.IsEmpty())
tsepezb4694242016-08-15 16:44:55 -0700480 m_pArray = pRuntime->NewArray();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700481
482 return m_pArray;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700483}
484
tsepezf3c88322016-08-09 07:30:38 -0700485CJS_Date::CJS_Date() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700486
tsepezb4694242016-08-15 16:44:55 -0700487CJS_Date::CJS_Date(CJS_Runtime* pRuntime, double dMsecTime)
488 : m_pDate(pRuntime->NewDate(dMsecTime)) {}
Tom Sepez67fd5df2015-10-08 12:24:19 -0700489
tsepezb4694242016-08-15 16:44:55 -0700490CJS_Date::CJS_Date(CJS_Runtime* pRuntime,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700491 int year,
492 int mon,
493 int day,
494 int hour,
495 int min,
Tom Sepez67fd5df2015-10-08 12:24:19 -0700496 int sec)
tsepezb4694242016-08-15 16:44:55 -0700497 : m_pDate(pRuntime->NewDate(MakeDate(year, mon, day, hour, min, sec, 0))) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700498
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700499CJS_Date::~CJS_Date() {}
500
tsepezb4694242016-08-15 16:44:55 -0700501bool CJS_Date::IsValidDate(CJS_Runtime* pRuntime) const {
Tom Sepezdf950b82017-08-04 11:33:49 -0700502 return !m_pDate.IsEmpty() && !std::isnan(pRuntime->ToDouble(m_pDate));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700503}
504
tsepez135b9982016-08-05 09:32:50 -0700505void CJS_Date::Attach(v8::Local<v8::Date> pDate) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700506 m_pDate = pDate;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700507}
508
tsepezb4694242016-08-15 16:44:55 -0700509int CJS_Date::GetYear(CJS_Runtime* pRuntime) const {
510 if (!IsValidDate(pRuntime))
tsepezfbf52c22016-07-25 11:17:07 -0700511 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700512
tsepeze6cf0132017-01-18 14:38:18 -0800513 return JS_GetYearFromTime(JS_LocalTime(pRuntime->ToDouble(m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700514}
515
tsepezb4694242016-08-15 16:44:55 -0700516void CJS_Date::SetYear(CJS_Runtime* pRuntime, int iYear) {
517 m_pDate = pRuntime->NewDate(
518 MakeDate(iYear, GetMonth(pRuntime), GetDay(pRuntime), GetHours(pRuntime),
519 GetMinutes(pRuntime), GetSeconds(pRuntime), 0));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700520}
521
tsepezb4694242016-08-15 16:44:55 -0700522int CJS_Date::GetMonth(CJS_Runtime* pRuntime) const {
523 if (!IsValidDate(pRuntime))
tsepezfbf52c22016-07-25 11:17:07 -0700524 return 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700525
tsepeze6cf0132017-01-18 14:38:18 -0800526 return JS_GetMonthFromTime(JS_LocalTime(pRuntime->ToDouble(m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700527}
528
tsepezb4694242016-08-15 16:44:55 -0700529void CJS_Date::SetMonth(CJS_Runtime* pRuntime, int iMonth) {
530 m_pDate = pRuntime->NewDate(
531 MakeDate(GetYear(pRuntime), iMonth, GetDay(pRuntime), GetHours(pRuntime),
532 GetMinutes(pRuntime), GetSeconds(pRuntime), 0));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700533}
534
tsepezb4694242016-08-15 16:44:55 -0700535int CJS_Date::GetDay(CJS_Runtime* pRuntime) const {
536 if (!IsValidDate(pRuntime))
tsepezfbf52c22016-07-25 11:17:07 -0700537 return 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700538
tsepeze6cf0132017-01-18 14:38:18 -0800539 return JS_GetDayFromTime(JS_LocalTime(pRuntime->ToDouble(m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700540}
541
tsepezb4694242016-08-15 16:44:55 -0700542void CJS_Date::SetDay(CJS_Runtime* pRuntime, int iDay) {
543 m_pDate = pRuntime->NewDate(
544 MakeDate(GetYear(pRuntime), GetMonth(pRuntime), iDay, GetHours(pRuntime),
545 GetMinutes(pRuntime), GetSeconds(pRuntime), 0));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700546}
547
tsepezb4694242016-08-15 16:44:55 -0700548int CJS_Date::GetHours(CJS_Runtime* pRuntime) const {
549 if (!IsValidDate(pRuntime))
tsepezfbf52c22016-07-25 11:17:07 -0700550 return 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700551
tsepeze6cf0132017-01-18 14:38:18 -0800552 return JS_GetHourFromTime(JS_LocalTime(pRuntime->ToDouble(m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700553}
554
tsepezb4694242016-08-15 16:44:55 -0700555void CJS_Date::SetHours(CJS_Runtime* pRuntime, int iHours) {
556 m_pDate = pRuntime->NewDate(
557 MakeDate(GetYear(pRuntime), GetMonth(pRuntime), GetDay(pRuntime), iHours,
558 GetMinutes(pRuntime), GetSeconds(pRuntime), 0));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700559}
560
tsepezb4694242016-08-15 16:44:55 -0700561int CJS_Date::GetMinutes(CJS_Runtime* pRuntime) const {
562 if (!IsValidDate(pRuntime))
tsepezfbf52c22016-07-25 11:17:07 -0700563 return 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700564
tsepeze6cf0132017-01-18 14:38:18 -0800565 return JS_GetMinFromTime(JS_LocalTime(pRuntime->ToDouble(m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700566}
567
tsepezb4694242016-08-15 16:44:55 -0700568void CJS_Date::SetMinutes(CJS_Runtime* pRuntime, int minutes) {
569 m_pDate = pRuntime->NewDate(MakeDate(GetYear(pRuntime), GetMonth(pRuntime),
570 GetDay(pRuntime), GetHours(pRuntime),
571 minutes, GetSeconds(pRuntime), 0));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700572}
573
tsepezb4694242016-08-15 16:44:55 -0700574int CJS_Date::GetSeconds(CJS_Runtime* pRuntime) const {
575 if (!IsValidDate(pRuntime))
tsepezfbf52c22016-07-25 11:17:07 -0700576 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700577
tsepeze6cf0132017-01-18 14:38:18 -0800578 return JS_GetSecFromTime(JS_LocalTime(pRuntime->ToDouble(m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700579}
580
tsepezb4694242016-08-15 16:44:55 -0700581void CJS_Date::SetSeconds(CJS_Runtime* pRuntime, int seconds) {
582 m_pDate = pRuntime->NewDate(MakeDate(GetYear(pRuntime), GetMonth(pRuntime),
583 GetDay(pRuntime), GetHours(pRuntime),
584 GetMinutes(pRuntime), seconds, 0));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700585}
586
tsepezb4694242016-08-15 16:44:55 -0700587double CJS_Date::ToDouble(CJS_Runtime* pRuntime) const {
tsepeze6cf0132017-01-18 14:38:18 -0800588 return !m_pDate.IsEmpty() ? pRuntime->ToDouble(m_pDate) : 0.0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700589}
590
Ryan Harrison275e2602017-09-18 14:23:18 -0400591WideString CJS_Date::ToString(CJS_Runtime* pRuntime) const {
592 return !m_pDate.IsEmpty() ? pRuntime->ToWideString(m_pDate) : WideString();
tsepezf3c88322016-08-09 07:30:38 -0700593}
tsepezfbf52c22016-07-25 11:17:07 -0700594
tsepezb4694242016-08-15 16:44:55 -0700595v8::Local<v8::Date> CJS_Date::ToV8Date(CJS_Runtime* pRuntime) const {
tsepezf3c88322016-08-09 07:30:38 -0700596 return m_pDate;
Tom Sepez39bfe122015-09-17 15:25:23 -0700597}
598
Tom Sepez39bfe122015-09-17 15:25:23 -0700599double JS_GetDateTime() {
600 if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
601 return 0;
thestig1cd352e2016-06-07 17:53:06 -0700602 time_t t = time(nullptr);
Tom Sepez39bfe122015-09-17 15:25:23 -0700603 struct tm* pTm = localtime(&t);
604
605 int year = pTm->tm_year + 1900;
Lei Zhangab5939e2017-06-16 02:23:18 -0700606 double t1 = TimeFromYear(year);
Tom Sepez39bfe122015-09-17 15:25:23 -0700607
608 return t1 + pTm->tm_yday * 86400000.0 + pTm->tm_hour * 3600000.0 +
609 pTm->tm_min * 60000.0 + pTm->tm_sec * 1000.0;
610}
611
612int JS_GetYearFromTime(double dt) {
Lei Zhangab5939e2017-06-16 02:23:18 -0700613 return YearFromTime(dt);
Tom Sepez39bfe122015-09-17 15:25:23 -0700614}
615
616int JS_GetMonthFromTime(double dt) {
Lei Zhangab5939e2017-06-16 02:23:18 -0700617 return MonthFromTime(dt);
Tom Sepez39bfe122015-09-17 15:25:23 -0700618}
619
620int JS_GetDayFromTime(double dt) {
Lei Zhangab5939e2017-06-16 02:23:18 -0700621 return DateFromTime(dt);
Tom Sepez39bfe122015-09-17 15:25:23 -0700622}
623
624int JS_GetHourFromTime(double dt) {
Lei Zhangab5939e2017-06-16 02:23:18 -0700625 return (int)Mod(floor(dt / (60 * 60 * 1000)), 24);
Tom Sepez39bfe122015-09-17 15:25:23 -0700626}
627
628int JS_GetMinFromTime(double dt) {
Lei Zhangab5939e2017-06-16 02:23:18 -0700629 return (int)Mod(floor(dt / (60 * 1000)), 60);
Tom Sepez39bfe122015-09-17 15:25:23 -0700630}
631
632int JS_GetSecFromTime(double dt) {
Lei Zhangab5939e2017-06-16 02:23:18 -0700633 return (int)Mod(floor(dt / 1000), 60);
Tom Sepez39bfe122015-09-17 15:25:23 -0700634}
635
Ryan Harrison275e2602017-09-18 14:23:18 -0400636double JS_DateParse(const WideString& str) {
Tom Sepez39bfe122015-09-17 15:25:23 -0700637 v8::Isolate* pIsolate = v8::Isolate::GetCurrent();
638 v8::Isolate::Scope isolate_scope(pIsolate);
639 v8::HandleScope scope(pIsolate);
640
641 v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
642
643 // Use the built-in object method.
644 v8::Local<v8::Value> v =
645 context->Global()
646 ->Get(context, v8::String::NewFromUtf8(pIsolate, "Date",
647 v8::NewStringType::kNormal)
648 .ToLocalChecked())
649 .ToLocalChecked();
650 if (v->IsObject()) {
651 v8::Local<v8::Object> o = v->ToObject(context).ToLocalChecked();
652 v = o->Get(context, v8::String::NewFromUtf8(pIsolate, "parse",
653 v8::NewStringType::kNormal)
Dan Sinclairf766ad22016-03-14 13:51:24 -0400654 .ToLocalChecked())
655 .ToLocalChecked();
Tom Sepez39bfe122015-09-17 15:25:23 -0700656 if (v->IsFunction()) {
657 v8::Local<v8::Function> funC = v8::Local<v8::Function>::Cast(v);
Tom Sepez39bfe122015-09-17 15:25:23 -0700658 const int argc = 1;
Tom Sepezc6dc69f2017-02-23 09:53:09 -0800659 v8::Local<v8::Value> timeStr =
660 CJS_Runtime::CurrentRuntimeFromIsolate(pIsolate)->NewString(
Ryan Harrison275e2602017-09-18 14:23:18 -0400661 str.AsStringView());
Tom Sepez39bfe122015-09-17 15:25:23 -0700662 v8::Local<v8::Value> argv[argc] = {timeStr};
663 v = funC->Call(context, context->Global(), argc, argv).ToLocalChecked();
664 if (v->IsNumber()) {
665 double date = v->ToNumber(context).ToLocalChecked()->Value();
Tom Sepezdf950b82017-08-04 11:33:49 -0700666 if (!std::isfinite(date))
Tom Sepez39bfe122015-09-17 15:25:23 -0700667 return date;
tsepez86a61dc2016-03-25 10:00:11 -0700668 return JS_LocalTime(date);
Tom Sepez39bfe122015-09-17 15:25:23 -0700669 }
670 }
671 }
672 return 0;
673}
674
675double JS_MakeDay(int nYear, int nMonth, int nDate) {
Tom Sepezdf950b82017-08-04 11:33:49 -0700676 double y = static_cast<double>(nYear);
677 double m = static_cast<double>(nMonth);
678 double dt = static_cast<double>(nDate);
679 double ym = y + floor(m / 12);
Lei Zhangab5939e2017-06-16 02:23:18 -0700680 double mn = Mod(m, 12);
Tom Sepezdf950b82017-08-04 11:33:49 -0700681 double t = TimeFromYearMonth(static_cast<int>(ym), static_cast<int>(mn));
Lei Zhangab5939e2017-06-16 02:23:18 -0700682 if (YearFromTime(t) != ym || MonthFromTime(t) != mn || DateFromTime(t) != 1)
Tom Sepezdf950b82017-08-04 11:33:49 -0700683 return std::nan("");
684
Lei Zhangab5939e2017-06-16 02:23:18 -0700685 return Day(t) + dt - 1;
Tom Sepez39bfe122015-09-17 15:25:23 -0700686}
687
688double JS_MakeTime(int nHour, int nMin, int nSec, int nMs) {
Tom Sepezdf950b82017-08-04 11:33:49 -0700689 double h = static_cast<double>(nHour);
690 double m = static_cast<double>(nMin);
691 double s = static_cast<double>(nSec);
692 double milli = static_cast<double>(nMs);
Tom Sepez39bfe122015-09-17 15:25:23 -0700693 return h * 3600000 + m * 60000 + s * 1000 + milli;
694}
695
696double JS_MakeDate(double day, double time) {
Tom Sepezdf950b82017-08-04 11:33:49 -0700697 if (!std::isfinite(day) || !std::isfinite(time))
698 return std::nan("");
Tom Sepez39bfe122015-09-17 15:25:23 -0700699
700 return day * 86400000 + time;
701}
702
Tom Sepez39bfe122015-09-17 15:25:23 -0700703double JS_LocalTime(double d) {
Lei Zhangab5939e2017-06-16 02:23:18 -0700704 return d + GetLocalTZA() + GetDaylightSavingTA(d);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700705}
Tom Sepezbd932572016-01-29 09:10:41 -0800706
707std::vector<CJS_Value> JS_ExpandKeywordParams(
708 CJS_Runtime* pRuntime,
709 const std::vector<CJS_Value>& originals,
710 size_t nKeywords,
711 ...) {
712 ASSERT(nKeywords);
713
714 std::vector<CJS_Value> result(nKeywords, CJS_Value(pRuntime));
715 size_t size = std::min(originals.size(), nKeywords);
716 for (size_t i = 0; i < size; ++i)
717 result[i] = originals[i];
718
719 if (originals.size() != 1 || originals[0].GetType() != CJS_Value::VT_object ||
720 originals[0].IsArrayObject()) {
721 return result;
722 }
tsepezb4694242016-08-15 16:44:55 -0700723 v8::Local<v8::Object> pObj = originals[0].ToV8Object(pRuntime);
Tom Sepezbd932572016-01-29 09:10:41 -0800724 result[0] = CJS_Value(pRuntime); // Make unknown.
725
726 va_list ap;
727 va_start(ap, nKeywords);
Wei Li89409932016-03-28 10:33:33 -0700728 for (size_t i = 0; i < nKeywords; ++i) {
Tom Sepezbd932572016-01-29 09:10:41 -0800729 const wchar_t* property = va_arg(ap, const wchar_t*);
tsepezb4694242016-08-15 16:44:55 -0700730 v8::Local<v8::Value> v8Value = pRuntime->GetObjectProperty(pObj, property);
Tom Sepezbd932572016-01-29 09:10:41 -0800731 if (!v8Value->IsUndefined())
tsepez40faa792016-07-15 17:58:02 -0700732 result[i] = CJS_Value(pRuntime, v8Value);
Tom Sepezbd932572016-01-29 09:10:41 -0800733 }
734 va_end(ap);
735 return result;
736}