blob: 6bc45c555d0808790abfa0fd14f71644bb0858dc [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
tsepezc3255f52016-03-25 14:52:27 -070020static const uint32_t g_nan[2] = {0, 0x7FF80000};
Tom Sepez39bfe122015-09-17 15:25:23 -070021static double GetNan() {
22 return *(double*)g_nan;
23}
24
Tom Sepez67fd5df2015-10-08 12:24:19 -070025CJS_Value::CJS_Value(CJS_Runtime* pRuntime)
Dan Sinclairf766ad22016-03-14 13:51:24 -040026 : m_eType(VT_unknown), m_pJSRuntime(pRuntime) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -070027
Tom Sepez67fd5df2015-10-08 12:24:19 -070028CJS_Value::CJS_Value(CJS_Runtime* pRuntime, v8::Local<v8::Value> pValue, Type t)
Dan Sinclairf766ad22016-03-14 13:51:24 -040029 : m_eType(t), m_pValue(pValue), m_pJSRuntime(pRuntime) {}
Tom Sepez67fd5df2015-10-08 12:24:19 -070030
31CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const int& iValue)
32 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070033 operator=(iValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070034}
35
Tom Sepez67fd5df2015-10-08 12:24:19 -070036CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const bool& bValue)
37 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070038 operator=(bValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070039}
40
Tom Sepez67fd5df2015-10-08 12:24:19 -070041CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const float& fValue)
42 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070043 operator=(fValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070044}
45
Tom Sepez67fd5df2015-10-08 12:24:19 -070046CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const double& dValue)
47 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070048 operator=(dValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070049}
50
Tom Sepez67fd5df2015-10-08 12:24:19 -070051CJS_Value::CJS_Value(CJS_Runtime* pRuntime, v8::Local<v8::Object> pJsObj)
52 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070053 operator=(pJsObj);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070054}
55
Tom Sepez67fd5df2015-10-08 12:24:19 -070056CJS_Value::CJS_Value(CJS_Runtime* pRuntime, CJS_Object* pJsObj)
57 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070058 operator=(pJsObj);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070059}
60
Tom Sepez67fd5df2015-10-08 12:24:19 -070061CJS_Value::CJS_Value(CJS_Runtime* pRuntime, CJS_Document* pJsDoc)
62 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070063 m_eType = VT_object;
64 if (pJsDoc)
Tom Sepez116e4ad2015-09-21 09:22:05 -070065 m_pValue = pJsDoc->ToV8Object();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070066}
67
Tom Sepez67fd5df2015-10-08 12:24:19 -070068CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const FX_WCHAR* pWstr)
69 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070070 operator=(pWstr);
Tom Sepezf79a69c2014-10-30 13:23:42 -070071}
72
Tom Sepez67fd5df2015-10-08 12:24:19 -070073CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const FX_CHAR* pStr)
74 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070075 operator=(pStr);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070076}
77
Tom Sepez67fd5df2015-10-08 12:24:19 -070078CJS_Value::CJS_Value(CJS_Runtime* pRuntime, CJS_Array& array)
79 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070080 operator=(array);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070081}
82
Nico Weber9d8ec5a2015-08-04 13:00:21 -070083CJS_Value::~CJS_Value() {}
84
weili625ad662016-06-15 11:21:33 -070085CJS_Value::CJS_Value(const CJS_Value& other) = default;
86
Tom Sepez39bfe122015-09-17 15:25:23 -070087void CJS_Value::Attach(v8::Local<v8::Value> pValue, Type t) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070088 m_pValue = pValue;
89 m_eType = t;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070090}
91
Nico Weber9d8ec5a2015-08-04 13:00:21 -070092void CJS_Value::Attach(CJS_Value* pValue) {
93 if (pValue)
94 Attach(pValue->ToV8Value(), pValue->GetType());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070095}
96
Nico Weber9d8ec5a2015-08-04 13:00:21 -070097void CJS_Value::Detach() {
98 m_pValue = v8::Local<v8::Value>();
99 m_eType = VT_unknown;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700100}
101
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700102int CJS_Value::ToInt() const {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700103 return FXJS_ToInt32(m_pJSRuntime->GetIsolate(), m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700104}
105
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700106bool CJS_Value::ToBool() const {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700107 return FXJS_ToBoolean(m_pJSRuntime->GetIsolate(), m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700108}
109
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700110double CJS_Value::ToDouble() const {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700111 return FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700112}
113
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700114float CJS_Value::ToFloat() const {
115 return (float)ToDouble();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700116}
117
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700118CJS_Object* CJS_Value::ToCJSObject() const {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700119 v8::Local<v8::Object> pObj =
120 FXJS_ToObject(m_pJSRuntime->GetIsolate(), m_pValue);
121 return (CJS_Object*)FXJS_GetPrivate(m_pJSRuntime->GetIsolate(), pObj);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700122}
123
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700124v8::Local<v8::Object> CJS_Value::ToV8Object() const {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700125 return FXJS_ToObject(m_pJSRuntime->GetIsolate(), m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700126}
127
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700128CFX_WideString CJS_Value::ToCFXWideString() const {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700129 return FXJS_ToString(m_pJSRuntime->GetIsolate(), m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700130}
131
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700132CFX_ByteString CJS_Value::ToCFXByteString() const {
133 return CFX_ByteString::FromUnicode(ToCFXWideString());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700134}
135
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700136v8::Local<v8::Value> CJS_Value::ToV8Value() const {
137 return m_pValue;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700138}
139
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700140v8::Local<v8::Array> CJS_Value::ToV8Array() const {
141 if (IsArrayObject())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700142 return v8::Local<v8::Array>::Cast(
143 FXJS_ToObject(m_pJSRuntime->GetIsolate(), m_pValue));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700144 return v8::Local<v8::Array>();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700145}
146
Tom Sepez4246b002016-01-20 11:48:29 -0800147void CJS_Value::MaybeCoerceToNumber() {
148 bool bAllowNaN = false;
149 if (m_eType == VT_string) {
150 CFX_ByteString bstr = ToCFXByteString();
151 if (bstr.GetLength() == 0)
152 return;
153 if (bstr == "NaN")
154 bAllowNaN = true;
155 }
etiennebb2f6f912016-04-27 09:10:09 -0700156 v8::TryCatch try_catch(m_pJSRuntime->GetIsolate());
Tom Sepez4246b002016-01-20 11:48:29 -0800157 v8::MaybeLocal<v8::Number> maybeNum =
158 m_pValue->ToNumber(m_pJSRuntime->GetIsolate()->GetCurrentContext());
159 if (maybeNum.IsEmpty())
160 return;
161 v8::Local<v8::Number> num = maybeNum.ToLocalChecked();
162 if (std::isnan(num->Value()) && !bAllowNaN)
163 return;
164 m_pValue = num;
165 m_eType = VT_number;
166}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700167
168void CJS_Value::operator=(int iValue) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700169 m_pValue = FXJS_NewNumber(m_pJSRuntime->GetIsolate(), iValue);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700170 m_eType = VT_number;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700171}
172
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700173void CJS_Value::operator=(bool bValue) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700174 m_pValue = FXJS_NewBoolean(m_pJSRuntime->GetIsolate(), bValue);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700175 m_eType = VT_boolean;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700176}
177
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700178void CJS_Value::operator=(double dValue) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700179 m_pValue = FXJS_NewNumber(m_pJSRuntime->GetIsolate(), dValue);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700180 m_eType = VT_number;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700181}
182
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700183void CJS_Value::operator=(float fValue) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700184 m_pValue = FXJS_NewNumber(m_pJSRuntime->GetIsolate(), fValue);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700185 m_eType = VT_number;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700186}
187
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700188void CJS_Value::operator=(v8::Local<v8::Object> pObj) {
tsepez88b66862016-07-14 12:07:48 -0700189 m_pValue = pObj;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700190 m_eType = VT_fxobject;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700191}
192
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700193void CJS_Value::operator=(CJS_Object* pObj) {
194 if (pObj)
Tom Sepez116e4ad2015-09-21 09:22:05 -0700195 operator=(pObj->ToV8Object());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700196}
197
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700198void CJS_Value::operator=(CJS_Document* pJsDoc) {
199 m_eType = VT_object;
200 if (pJsDoc) {
Tom Sepez116e4ad2015-09-21 09:22:05 -0700201 m_pValue = pJsDoc->ToV8Object();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700202 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700203}
204
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700205void CJS_Value::operator=(const FX_WCHAR* pWstr) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700206 m_pValue = FXJS_NewString(m_pJSRuntime->GetIsolate(), (wchar_t*)pWstr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700207 m_eType = VT_string;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700208}
209
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700210void CJS_Value::SetNull() {
tsepez88b66862016-07-14 12:07:48 -0700211 m_pValue = FXJS_NewNull(m_pJSRuntime->GetIsolate());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700212 m_eType = VT_null;
JUN FANG33f6f0d2015-04-06 12:39:51 -0700213}
214
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700215void CJS_Value::operator=(const FX_CHAR* pStr) {
216 operator=(CFX_WideString::FromLocal(pStr).c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700217}
218
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700219void CJS_Value::operator=(CJS_Array& array) {
tsepez88b66862016-07-14 12:07:48 -0700220 m_pValue = static_cast<v8::Local<v8::Array>>(array);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700221 m_eType = VT_object;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700222}
223
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700224void CJS_Value::operator=(CJS_Date& date) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700225 m_pValue = FXJS_NewDate(m_pJSRuntime->GetIsolate(), (double)date);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700226 m_eType = VT_date;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700227}
228
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700229void CJS_Value::operator=(CJS_Value value) {
230 m_pValue = value.ToV8Value();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700231 m_eType = value.m_eType;
Tom Sepez67fd5df2015-10-08 12:24:19 -0700232 m_pJSRuntime = value.m_pJSRuntime;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700233}
234
Tom Sepez39bfe122015-09-17 15:25:23 -0700235CJS_Value::Type CJS_Value::GetType() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700236 if (m_pValue.IsEmpty())
237 return VT_unknown;
238 if (m_pValue->IsString())
239 return VT_string;
240 if (m_pValue->IsNumber())
241 return VT_number;
242 if (m_pValue->IsBoolean())
243 return VT_boolean;
244 if (m_pValue->IsDate())
245 return VT_date;
246 if (m_pValue->IsObject())
247 return VT_object;
248 if (m_pValue->IsNull())
249 return VT_null;
250 if (m_pValue->IsUndefined())
251 return VT_undefined;
252 return VT_unknown;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700253}
254
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700255FX_BOOL CJS_Value::IsArrayObject() const {
256 if (m_pValue.IsEmpty())
257 return FALSE;
258 return m_pValue->IsArray();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700259}
260
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700261FX_BOOL CJS_Value::IsDateObject() const {
262 if (m_pValue.IsEmpty())
263 return FALSE;
264 return m_pValue->IsDate();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700265}
266
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700267// CJS_Value::operator CJS_Array()
268FX_BOOL CJS_Value::ConvertToArray(CJS_Array& array) const {
269 if (IsArrayObject()) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700270 array.Attach(FXJS_ToArray(m_pJSRuntime->GetIsolate(), m_pValue));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700271 return TRUE;
272 }
273
274 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700275}
276
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700277FX_BOOL CJS_Value::ConvertToDate(CJS_Date& date) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700278 if (IsDateObject()) {
279 date.Attach(m_pValue);
280 return TRUE;
281 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700282
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700283 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700284}
285
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700286CJS_PropValue::CJS_PropValue(const CJS_Value& value)
287 : CJS_Value(value), m_bIsSetting(0) {}
288
Tom Sepez67fd5df2015-10-08 12:24:19 -0700289CJS_PropValue::CJS_PropValue(CJS_Runtime* pRuntime)
Dan Sinclairf766ad22016-03-14 13:51:24 -0400290 : CJS_Value(pRuntime), m_bIsSetting(0) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700291
Dan Sinclairf766ad22016-03-14 13:51:24 -0400292CJS_PropValue::~CJS_PropValue() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700293
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700294void CJS_PropValue::operator<<(int iValue) {
295 ASSERT(!m_bIsSetting);
296 CJS_Value::operator=(iValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700297}
298
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700299void CJS_PropValue::operator>>(int& iValue) const {
300 ASSERT(m_bIsSetting);
301 iValue = CJS_Value::ToInt();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700302}
303
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700304void CJS_PropValue::operator<<(bool bValue) {
305 ASSERT(!m_bIsSetting);
306 CJS_Value::operator=(bValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700307}
308
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700309void CJS_PropValue::operator>>(bool& bValue) const {
310 ASSERT(m_bIsSetting);
311 bValue = CJS_Value::ToBool();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700312}
313
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700314void CJS_PropValue::operator<<(double dValue) {
315 ASSERT(!m_bIsSetting);
316 CJS_Value::operator=(dValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700317}
318
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700319void CJS_PropValue::operator>>(double& dValue) const {
320 ASSERT(m_bIsSetting);
321 dValue = CJS_Value::ToDouble();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700322}
323
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700324void CJS_PropValue::operator<<(CJS_Object* pObj) {
325 ASSERT(!m_bIsSetting);
326 CJS_Value::operator=(pObj);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700327}
328
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700329void CJS_PropValue::operator>>(CJS_Object*& ppObj) const {
330 ASSERT(m_bIsSetting);
331 ppObj = CJS_Value::ToCJSObject();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700332}
333
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700334void CJS_PropValue::operator<<(CJS_Document* pJsDoc) {
335 ASSERT(!m_bIsSetting);
336 CJS_Value::operator=(pJsDoc);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700337}
338
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700339void CJS_PropValue::operator>>(CJS_Document*& ppJsDoc) const {
340 ASSERT(m_bIsSetting);
341 ppJsDoc = static_cast<CJS_Document*>(CJS_Value::ToCJSObject());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700342}
343
Tom Sepez808a99e2015-09-10 12:28:37 -0700344void CJS_PropValue::operator<<(v8::Local<v8::Object> pObj) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700345 ASSERT(!m_bIsSetting);
346 CJS_Value::operator=(pObj);
JUN FANG33f6f0d2015-04-06 12:39:51 -0700347}
348
Tom Sepez808a99e2015-09-10 12:28:37 -0700349void CJS_PropValue::operator>>(v8::Local<v8::Object>& ppObj) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700350 ASSERT(m_bIsSetting);
351 ppObj = CJS_Value::ToV8Object();
JUN FANG33f6f0d2015-04-06 12:39:51 -0700352}
353
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700354void CJS_PropValue::StartSetting() {
355 m_bIsSetting = 1;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700356}
357
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700358void CJS_PropValue::StartGetting() {
359 m_bIsSetting = 0;
360}
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500361void CJS_PropValue::operator<<(CFX_ByteString str) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700362 ASSERT(!m_bIsSetting);
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500363 CJS_Value::operator=(str.c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700364}
365
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500366void CJS_PropValue::operator>>(CFX_ByteString& str) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700367 ASSERT(m_bIsSetting);
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500368 str = CJS_Value::ToCFXByteString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700369}
370
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700371void CJS_PropValue::operator<<(const FX_WCHAR* c_string) {
372 ASSERT(!m_bIsSetting);
373 CJS_Value::operator=(c_string);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700374}
375
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700376void CJS_PropValue::operator>>(CFX_WideString& wide_string) const {
377 ASSERT(m_bIsSetting);
378 wide_string = CJS_Value::ToCFXWideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700379}
380
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700381void CJS_PropValue::operator<<(CFX_WideString wide_string) {
382 ASSERT(!m_bIsSetting);
383 CJS_Value::operator=(wide_string.c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700384}
385
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700386void CJS_PropValue::operator>>(CJS_Array& array) const {
387 ASSERT(m_bIsSetting);
388 ConvertToArray(array);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700389}
390
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700391void CJS_PropValue::operator<<(CJS_Array& array) {
392 ASSERT(!m_bIsSetting);
393 CJS_Value::operator=(array);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700394}
395
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700396void CJS_PropValue::operator>>(CJS_Date& date) const {
397 ASSERT(m_bIsSetting);
398 ConvertToDate(date);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700399}
400
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700401void CJS_PropValue::operator<<(CJS_Date& date) {
402 ASSERT(!m_bIsSetting);
403 CJS_Value::operator=(date);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700404}
405
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700406CJS_PropValue::operator v8::Local<v8::Value>() const {
407 return m_pValue;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700408}
409
Dan Sinclairf766ad22016-03-14 13:51:24 -0400410CJS_Array::CJS_Array(CJS_Runtime* pRuntime) : m_pJSRuntime(pRuntime) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700411
412CJS_Array::~CJS_Array() {}
413
weili625ad662016-06-15 11:21:33 -0700414CJS_Array::CJS_Array(const CJS_Array& other) = default;
415
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700416void CJS_Array::Attach(v8::Local<v8::Array> pArray) {
417 m_pArray = pArray;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700418}
419
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700420FX_BOOL CJS_Array::IsAttached() {
421 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700422}
423
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700424void CJS_Array::GetElement(unsigned index, CJS_Value& value) {
425 if (m_pArray.IsEmpty())
426 return;
Tom Sepez67fd5df2015-10-08 12:24:19 -0700427 v8::Local<v8::Value> p =
428 FXJS_GetArrayElement(m_pJSRuntime->GetIsolate(), m_pArray, index);
Tom Sepez39bfe122015-09-17 15:25:23 -0700429 value.Attach(p, CJS_Value::VT_object);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700430}
431
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700432void CJS_Array::SetElement(unsigned index, CJS_Value value) {
433 if (m_pArray.IsEmpty())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700434 m_pArray = FXJS_NewArray(m_pJSRuntime->GetIsolate());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700435
Tom Sepez67fd5df2015-10-08 12:24:19 -0700436 FXJS_PutArrayElement(m_pJSRuntime->GetIsolate(), m_pArray, index,
437 value.ToV8Value());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700438}
439
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700440int CJS_Array::GetLength() {
441 if (m_pArray.IsEmpty())
442 return 0;
Tom Sepez39bfe122015-09-17 15:25:23 -0700443 return FXJS_GetArrayLength(m_pArray);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700444}
445
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700446CJS_Array::operator v8::Local<v8::Array>() {
447 if (m_pArray.IsEmpty())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700448 m_pArray = FXJS_NewArray(m_pJSRuntime->GetIsolate());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700449
450 return m_pArray;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700451}
452
Dan Sinclairf766ad22016-03-14 13:51:24 -0400453CJS_Date::CJS_Date(CJS_Runtime* pRuntime) : m_pJSRuntime(pRuntime) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700454
Tom Sepez67fd5df2015-10-08 12:24:19 -0700455CJS_Date::CJS_Date(CJS_Runtime* pRuntime, double dMsecTime)
456 : m_pJSRuntime(pRuntime) {
457 m_pDate = FXJS_NewDate(pRuntime->GetIsolate(), dMsecTime);
458}
459
460CJS_Date::CJS_Date(CJS_Runtime* pRuntime,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700461 int year,
462 int mon,
463 int day,
464 int hour,
465 int min,
Tom Sepez67fd5df2015-10-08 12:24:19 -0700466 int sec)
467 : m_pJSRuntime(pRuntime) {
468 m_pDate = FXJS_NewDate(pRuntime->GetIsolate(),
469 MakeDate(year, mon, day, hour, min, sec, 0));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700470}
471
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700472double CJS_Date::MakeDate(int year,
473 int mon,
474 int day,
475 int hour,
476 int min,
477 int sec,
478 int ms) {
479 return JS_MakeDate(JS_MakeDay(year, mon, day),
480 JS_MakeTime(hour, min, sec, ms));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700481}
482
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700483CJS_Date::~CJS_Date() {}
484
485FX_BOOL CJS_Date::IsValidDate() {
486 if (m_pDate.IsEmpty())
487 return FALSE;
Tom Sepez67fd5df2015-10-08 12:24:19 -0700488 return !JS_PortIsNan(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700489}
490
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700491void CJS_Date::Attach(v8::Local<v8::Value> pDate) {
492 m_pDate = pDate;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700493}
494
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700495int CJS_Date::GetYear() {
496 if (IsValidDate())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700497 return JS_GetYearFromTime(
498 JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700499
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700500 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700501}
502
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700503void CJS_Date::SetYear(int iYear) {
504 double date = MakeDate(iYear, GetMonth(), GetDay(), GetHours(), GetMinutes(),
505 GetSeconds(), 0);
Tom Sepez67fd5df2015-10-08 12:24:19 -0700506 FXJS_ValueCopy(m_pDate, FXJS_NewDate(m_pJSRuntime->GetIsolate(), date));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700507}
508
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700509int CJS_Date::GetMonth() {
510 if (IsValidDate())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700511 return JS_GetMonthFromTime(
512 JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700513
514 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700515}
516
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700517void CJS_Date::SetMonth(int iMonth) {
518 double date = MakeDate(GetYear(), iMonth, GetDay(), GetHours(), GetMinutes(),
519 GetSeconds(), 0);
Tom Sepez67fd5df2015-10-08 12:24:19 -0700520 FXJS_ValueCopy(m_pDate, FXJS_NewDate(m_pJSRuntime->GetIsolate(), date));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700521}
522
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700523int CJS_Date::GetDay() {
524 if (IsValidDate())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700525 return JS_GetDayFromTime(
526 JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700527
528 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700529}
530
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700531void CJS_Date::SetDay(int iDay) {
532 double date = MakeDate(GetYear(), GetMonth(), iDay, GetHours(), GetMinutes(),
533 GetSeconds(), 0);
Tom Sepez67fd5df2015-10-08 12:24:19 -0700534 FXJS_ValueCopy(m_pDate, FXJS_NewDate(m_pJSRuntime->GetIsolate(), date));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700535}
536
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700537int CJS_Date::GetHours() {
538 if (IsValidDate())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700539 return JS_GetHourFromTime(
540 JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700541
542 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700543}
544
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700545void CJS_Date::SetHours(int iHours) {
546 double date = MakeDate(GetYear(), GetMonth(), GetDay(), iHours, GetMinutes(),
547 GetSeconds(), 0);
Tom Sepez67fd5df2015-10-08 12:24:19 -0700548 FXJS_ValueCopy(m_pDate, FXJS_NewDate(m_pJSRuntime->GetIsolate(), date));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700549}
550
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700551int CJS_Date::GetMinutes() {
552 if (IsValidDate())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700553 return JS_GetMinFromTime(
554 JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700555
556 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700557}
558
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700559void CJS_Date::SetMinutes(int minutes) {
560 double date = MakeDate(GetYear(), GetMonth(), GetDay(), GetHours(), minutes,
561 GetSeconds(), 0);
Tom Sepez67fd5df2015-10-08 12:24:19 -0700562 FXJS_ValueCopy(m_pDate, FXJS_NewDate(m_pJSRuntime->GetIsolate(), date));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700563}
564
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700565int CJS_Date::GetSeconds() {
566 if (IsValidDate())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700567 return JS_GetSecFromTime(
568 JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700569
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700570 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700571}
572
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700573void CJS_Date::SetSeconds(int seconds) {
574 double date = MakeDate(GetYear(), GetMonth(), GetDay(), GetHours(),
575 GetMinutes(), seconds, 0);
Tom Sepez67fd5df2015-10-08 12:24:19 -0700576 FXJS_ValueCopy(m_pDate, FXJS_NewDate(m_pJSRuntime->GetIsolate(), date));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700577}
578
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700579CJS_Date::operator v8::Local<v8::Value>() {
580 return m_pDate;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700581}
582
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700583CJS_Date::operator double() const {
584 if (m_pDate.IsEmpty())
585 return 0.0;
Tom Sepez67fd5df2015-10-08 12:24:19 -0700586 return FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700587}
588
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700589CFX_WideString CJS_Date::ToString() const {
590 if (m_pDate.IsEmpty())
591 return L"";
Tom Sepez67fd5df2015-10-08 12:24:19 -0700592 return FXJS_ToString(m_pJSRuntime->GetIsolate(), m_pDate);
Tom Sepez39bfe122015-09-17 15:25:23 -0700593}
594
595double _getLocalTZA() {
596 if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
597 return 0;
598 time_t t = 0;
599 time(&t);
600 localtime(&t);
601#if _MSC_VER >= 1900
602 // In gcc and in Visual Studio prior to VS 2015 'timezone' is a global
603 // variable declared in time.h. That variable was deprecated and in VS 2015
604 // is removed, with _get_timezone replacing it.
605 long timezone = 0;
606 _get_timezone(&timezone);
607#endif
608 return (double)(-(timezone * 1000));
609}
610
611int _getDaylightSavingTA(double d) {
612 if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
613 return 0;
614 time_t t = (time_t)(d / 1000);
615 struct tm* tmp = localtime(&t);
Lei Zhang412e9082015-12-14 18:34:00 -0800616 if (!tmp)
Tom Sepez39bfe122015-09-17 15:25:23 -0700617 return 0;
618 if (tmp->tm_isdst > 0)
619 // One hour.
620 return (int)60 * 60 * 1000;
621 return 0;
622}
623
624double _Mod(double x, double y) {
625 double r = fmod(x, y);
626 if (r < 0)
627 r += y;
628 return r;
629}
630
631int _isfinite(double v) {
632#if _MSC_VER
633 return ::_finite(v);
634#else
635 return std::fabs(v) < std::numeric_limits<double>::max();
636#endif
637}
638
639double _toInteger(double n) {
640 return (n >= 0) ? FXSYS_floor(n) : -FXSYS_floor(-n);
641}
642
643bool _isLeapYear(int year) {
644 return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 != 0));
645}
646
647int _DayFromYear(int y) {
648 return (int)(365 * (y - 1970.0) + FXSYS_floor((y - 1969.0) / 4) -
649 FXSYS_floor((y - 1901.0) / 100) +
650 FXSYS_floor((y - 1601.0) / 400));
651}
652
653double _TimeFromYear(int y) {
Lei Zhang1ac47eb2015-12-21 11:04:44 -0800654 return 86400000.0 * _DayFromYear(y);
Tom Sepez39bfe122015-09-17 15:25:23 -0700655}
656
Tom Sepez4161c5c2016-03-21 12:26:54 -0700657static const uint16_t daysMonth[12] = {0, 31, 59, 90, 120, 151,
658 181, 212, 243, 273, 304, 334};
659static const uint16_t leapDaysMonth[12] = {0, 31, 60, 91, 121, 152,
660 182, 213, 244, 274, 305, 335};
661
Tom Sepez39bfe122015-09-17 15:25:23 -0700662double _TimeFromYearMonth(int y, int m) {
Tom Sepez4161c5c2016-03-21 12:26:54 -0700663 const uint16_t* pMonth = _isLeapYear(y) ? leapDaysMonth : daysMonth;
Tom Sepez39bfe122015-09-17 15:25:23 -0700664 return _TimeFromYear(y) + ((double)pMonth[m]) * 86400000;
665}
666
667int _Day(double t) {
668 return (int)FXSYS_floor(t / 86400000);
669}
670
671int _YearFromTime(double t) {
672 // estimate the time.
Lei Zhang1ac47eb2015-12-21 11:04:44 -0800673 int y = 1970 + static_cast<int>(t / (365.2425 * 86400000));
Tom Sepez39bfe122015-09-17 15:25:23 -0700674 if (_TimeFromYear(y) <= t) {
675 while (_TimeFromYear(y + 1) <= t)
676 y++;
Dan Sinclair738b08c2016-03-01 14:45:20 -0500677 } else {
Lei Zhang1ac47eb2015-12-21 11:04:44 -0800678 while (_TimeFromYear(y) > t)
Tom Sepez39bfe122015-09-17 15:25:23 -0700679 y--;
Dan Sinclair738b08c2016-03-01 14:45:20 -0500680 }
Tom Sepez39bfe122015-09-17 15:25:23 -0700681 return y;
682}
683
684int _DayWithinYear(double t) {
685 int year = _YearFromTime(t);
686 int day = _Day(t);
687 return day - _DayFromYear(year);
688}
689
690int _MonthFromTime(double t) {
691 int day = _DayWithinYear(t);
692 int year = _YearFromTime(t);
693 if (0 <= day && day < 31)
694 return 0;
695 if (31 <= day && day < 59 + _isLeapYear(year))
696 return 1;
697 if ((59 + _isLeapYear(year)) <= day && day < (90 + _isLeapYear(year)))
698 return 2;
699 if ((90 + _isLeapYear(year)) <= day && day < (120 + _isLeapYear(year)))
700 return 3;
701 if ((120 + _isLeapYear(year)) <= day && day < (151 + _isLeapYear(year)))
702 return 4;
703 if ((151 + _isLeapYear(year)) <= day && day < (181 + _isLeapYear(year)))
704 return 5;
705 if ((181 + _isLeapYear(year)) <= day && day < (212 + _isLeapYear(year)))
706 return 6;
707 if ((212 + _isLeapYear(year)) <= day && day < (243 + _isLeapYear(year)))
708 return 7;
709 if ((243 + _isLeapYear(year)) <= day && day < (273 + _isLeapYear(year)))
710 return 8;
711 if ((273 + _isLeapYear(year)) <= day && day < (304 + _isLeapYear(year)))
712 return 9;
713 if ((304 + _isLeapYear(year)) <= day && day < (334 + _isLeapYear(year)))
714 return 10;
715 if ((334 + _isLeapYear(year)) <= day && day < (365 + _isLeapYear(year)))
716 return 11;
717
718 return -1;
719}
720
721int _DateFromTime(double t) {
722 int day = _DayWithinYear(t);
723 int year = _YearFromTime(t);
weili12367cb2016-06-03 11:22:16 -0700724 int leap = _isLeapYear(year);
Tom Sepez39bfe122015-09-17 15:25:23 -0700725 int month = _MonthFromTime(t);
726 switch (month) {
727 case 0:
728 return day + 1;
729 case 1:
730 return day - 30;
731 case 2:
732 return day - 58 - leap;
733 case 3:
734 return day - 89 - leap;
735 case 4:
736 return day - 119 - leap;
737 case 5:
738 return day - 150 - leap;
739 case 6:
740 return day - 180 - leap;
741 case 7:
742 return day - 211 - leap;
743 case 8:
744 return day - 242 - leap;
745 case 9:
746 return day - 272 - leap;
747 case 10:
748 return day - 303 - leap;
749 case 11:
750 return day - 333 - leap;
751 default:
752 return 0;
753 }
754}
755
756double JS_GetDateTime() {
757 if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
758 return 0;
thestig1cd352e2016-06-07 17:53:06 -0700759 time_t t = time(nullptr);
Tom Sepez39bfe122015-09-17 15:25:23 -0700760 struct tm* pTm = localtime(&t);
761
762 int year = pTm->tm_year + 1900;
763 double t1 = _TimeFromYear(year);
764
765 return t1 + pTm->tm_yday * 86400000.0 + pTm->tm_hour * 3600000.0 +
766 pTm->tm_min * 60000.0 + pTm->tm_sec * 1000.0;
767}
768
769int JS_GetYearFromTime(double dt) {
770 return _YearFromTime(dt);
771}
772
773int JS_GetMonthFromTime(double dt) {
774 return _MonthFromTime(dt);
775}
776
777int JS_GetDayFromTime(double dt) {
778 return _DateFromTime(dt);
779}
780
781int JS_GetHourFromTime(double dt) {
tsepez86a61dc2016-03-25 10:00:11 -0700782 return (int)_Mod(floor(dt / (60 * 60 * 1000)), 24);
Tom Sepez39bfe122015-09-17 15:25:23 -0700783}
784
785int JS_GetMinFromTime(double dt) {
tsepez86a61dc2016-03-25 10:00:11 -0700786 return (int)_Mod(floor(dt / (60 * 1000)), 60);
Tom Sepez39bfe122015-09-17 15:25:23 -0700787}
788
789int JS_GetSecFromTime(double dt) {
tsepez86a61dc2016-03-25 10:00:11 -0700790 return (int)_Mod(floor(dt / 1000), 60);
Tom Sepez39bfe122015-09-17 15:25:23 -0700791}
792
tsepez018935c2016-04-15 13:15:12 -0700793double JS_DateParse(const CFX_WideString& str) {
Tom Sepez39bfe122015-09-17 15:25:23 -0700794 v8::Isolate* pIsolate = v8::Isolate::GetCurrent();
795 v8::Isolate::Scope isolate_scope(pIsolate);
796 v8::HandleScope scope(pIsolate);
797
798 v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
799
800 // Use the built-in object method.
801 v8::Local<v8::Value> v =
802 context->Global()
803 ->Get(context, v8::String::NewFromUtf8(pIsolate, "Date",
804 v8::NewStringType::kNormal)
805 .ToLocalChecked())
806 .ToLocalChecked();
807 if (v->IsObject()) {
808 v8::Local<v8::Object> o = v->ToObject(context).ToLocalChecked();
809 v = o->Get(context, v8::String::NewFromUtf8(pIsolate, "parse",
810 v8::NewStringType::kNormal)
Dan Sinclairf766ad22016-03-14 13:51:24 -0400811 .ToLocalChecked())
812 .ToLocalChecked();
Tom Sepez39bfe122015-09-17 15:25:23 -0700813 if (v->IsFunction()) {
814 v8::Local<v8::Function> funC = v8::Local<v8::Function>::Cast(v);
Tom Sepez39bfe122015-09-17 15:25:23 -0700815 const int argc = 1;
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500816 v8::Local<v8::String> timeStr = FXJS_WSToJSString(pIsolate, str);
Tom Sepez39bfe122015-09-17 15:25:23 -0700817 v8::Local<v8::Value> argv[argc] = {timeStr};
818 v = funC->Call(context, context->Global(), argc, argv).ToLocalChecked();
819 if (v->IsNumber()) {
820 double date = v->ToNumber(context).ToLocalChecked()->Value();
821 if (!_isfinite(date))
822 return date;
tsepez86a61dc2016-03-25 10:00:11 -0700823 return JS_LocalTime(date);
Tom Sepez39bfe122015-09-17 15:25:23 -0700824 }
825 }
826 }
827 return 0;
828}
829
830double JS_MakeDay(int nYear, int nMonth, int nDate) {
831 if (!_isfinite(nYear) || !_isfinite(nMonth) || !_isfinite(nDate))
832 return GetNan();
833 double y = _toInteger(nYear);
834 double m = _toInteger(nMonth);
835 double dt = _toInteger(nDate);
836 double ym = y + FXSYS_floor((double)m / 12);
837 double mn = _Mod(m, 12);
838
839 double t = _TimeFromYearMonth((int)ym, (int)mn);
840
841 if (_YearFromTime(t) != ym || _MonthFromTime(t) != mn ||
842 _DateFromTime(t) != 1)
843 return GetNan();
844 return _Day(t) + dt - 1;
845}
846
847double JS_MakeTime(int nHour, int nMin, int nSec, int nMs) {
848 if (!_isfinite(nHour) || !_isfinite(nMin) || !_isfinite(nSec) ||
849 !_isfinite(nMs))
850 return GetNan();
851
852 double h = _toInteger(nHour);
853 double m = _toInteger(nMin);
854 double s = _toInteger(nSec);
855 double milli = _toInteger(nMs);
856
857 return h * 3600000 + m * 60000 + s * 1000 + milli;
858}
859
860double JS_MakeDate(double day, double time) {
861 if (!_isfinite(day) || !_isfinite(time))
862 return GetNan();
863
864 return day * 86400000 + time;
865}
866
867bool JS_PortIsNan(double d) {
868 return d != d;
869}
870
871double JS_LocalTime(double d) {
tsepez86a61dc2016-03-25 10:00:11 -0700872 return d + _getLocalTZA() + _getDaylightSavingTA(d);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700873}
Tom Sepezbd932572016-01-29 09:10:41 -0800874
875std::vector<CJS_Value> JS_ExpandKeywordParams(
876 CJS_Runtime* pRuntime,
877 const std::vector<CJS_Value>& originals,
878 size_t nKeywords,
879 ...) {
880 ASSERT(nKeywords);
881
882 std::vector<CJS_Value> result(nKeywords, CJS_Value(pRuntime));
883 size_t size = std::min(originals.size(), nKeywords);
884 for (size_t i = 0; i < size; ++i)
885 result[i] = originals[i];
886
887 if (originals.size() != 1 || originals[0].GetType() != CJS_Value::VT_object ||
888 originals[0].IsArrayObject()) {
889 return result;
890 }
891 v8::Local<v8::Object> pObj = originals[0].ToV8Object();
892 result[0] = CJS_Value(pRuntime); // Make unknown.
893
894 va_list ap;
895 va_start(ap, nKeywords);
Wei Li89409932016-03-28 10:33:33 -0700896 for (size_t i = 0; i < nKeywords; ++i) {
Tom Sepezbd932572016-01-29 09:10:41 -0800897 const wchar_t* property = va_arg(ap, const wchar_t*);
898 v8::Local<v8::Value> v8Value =
899 FXJS_GetObjectElement(pRuntime->GetIsolate(), pObj, property);
900 if (!v8Value->IsUndefined())
901 result[i] = CJS_Value(pRuntime, v8Value, CJS_Value::VT_unknown);
902 }
903 va_end(ap);
904 return result;
905}