1 // 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. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #include "fxjs/cjs_global.h" 8 9 #include <map> 10 #include <memory> 11 #include <utility> 12 #include <vector> 13 14 #include "core/fxcrt/fx_extension.h" 15 #include "fxjs/JS_Define.h" 16 #include "fxjs/cjs_event_context.h" 17 #include "fxjs/cjs_eventhandler.h" 18 #include "fxjs/cjs_globaldata.h" 19 #include "fxjs/cjs_keyvalue.h" 20 #include "fxjs/cjs_object.h" 21 #include "fxjs/js_resources.h" 22 23 namespace { 24 25 WideString PropFromV8Prop(v8::Isolate* pIsolate, 26 v8::Local<v8::String> property) { 27 v8::String::Utf8Value utf8_value(pIsolate, property); 28 return WideString::FromUTF8(ByteStringView(*utf8_value, utf8_value.length())); 29 } 30 31 template <class Alt> 32 void JSSpecialPropQuery(const char*, 33 v8::Local<v8::String> property, 34 const v8::PropertyCallbackInfo<v8::Integer>& info) { 35 CJS_Runtime* pRuntime = 36 CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate()); 37 if (!pRuntime) 38 return; 39 40 CJS_Object* pJSObj = 41 static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder())); 42 if (!pJSObj) 43 return; 44 45 Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject()); 46 CJS_Return result = 47 pObj->QueryProperty(PropFromV8Prop(info.GetIsolate(), property).c_str()); 48 info.GetReturnValue().Set(!result.HasError() ? 4 : 0); 49 } 50 51 template <class Alt> 52 void JSSpecialPropGet(const char* class_name, 53 v8::Local<v8::String> property, 54 const v8::PropertyCallbackInfo<v8::Value>& info) { 55 CJS_Runtime* pRuntime = 56 CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate()); 57 if (!pRuntime) 58 return; 59 60 CJS_Object* pJSObj = 61 static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder())); 62 if (!pJSObj) 63 return; 64 65 Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject()); 66 CJS_Return result = pObj->GetProperty( 67 pRuntime, PropFromV8Prop(info.GetIsolate(), property).c_str()); 68 if (result.HasError()) { 69 pRuntime->Error( 70 JSFormatErrorString(class_name, "GetProperty", result.Error())); 71 return; 72 } 73 74 if (result.HasReturn()) 75 info.GetReturnValue().Set(result.Return()); 76 } 77 78 template <class Alt> 79 void JSSpecialPropPut(const char* class_name, 80 v8::Local<v8::String> property, 81 v8::Local<v8::Value> value, 82 const v8::PropertyCallbackInfo<v8::Value>& info) { 83 CJS_Runtime* pRuntime = 84 CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate()); 85 if (!pRuntime) 86 return; 87 88 CJS_Object* pJSObj = 89 static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder())); 90 if (!pJSObj) 91 return; 92 93 Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject()); 94 CJS_Return result = pObj->SetProperty( 95 pRuntime, PropFromV8Prop(info.GetIsolate(), property).c_str(), value); 96 if (result.HasError()) { 97 pRuntime->Error( 98 JSFormatErrorString(class_name, "PutProperty", result.Error())); 99 } 100 } 101 102 template <class Alt> 103 void JSSpecialPropDel(const char* class_name, 104 v8::Local<v8::String> property, 105 const v8::PropertyCallbackInfo<v8::Boolean>& info) { 106 CJS_Runtime* pRuntime = 107 CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate()); 108 if (!pRuntime) 109 return; 110 111 CJS_Object* pJSObj = 112 static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder())); 113 if (!pJSObj) 114 return; 115 116 Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject()); 117 CJS_Return result = pObj->DelProperty( 118 pRuntime, PropFromV8Prop(info.GetIsolate(), property).c_str()); 119 if (result.HasError()) { 120 // TODO(dsinclair): Should this set the pRuntime->Error result? 121 // ByteString cbName = 122 // ByteString::Format("%s.%s", class_name, "DelProperty"); 123 } 124 } 125 126 struct JSGlobalData { 127 JSGlobalData(); 128 ~JSGlobalData(); 129 130 JS_GlobalDataType nType; 131 double dData; 132 bool bData; 133 ByteString sData; 134 v8::Global<v8::Object> pData; 135 bool bPersistent; 136 bool bDeleted; 137 }; 138 139 class JSGlobalAlternate : public CJS_EmbedObj { 140 public: 141 explicit JSGlobalAlternate(CJS_Object* pJSObject); 142 ~JSGlobalAlternate() override; 143 144 CJS_Return setPersistent(CJS_Runtime* pRuntime, 145 const std::vector<v8::Local<v8::Value>>& params); 146 CJS_Return QueryProperty(const wchar_t* propname); 147 CJS_Return GetProperty(CJS_Runtime* pRuntime, const wchar_t* propname); 148 CJS_Return SetProperty(CJS_Runtime* pRuntime, 149 const wchar_t* propname, 150 v8::Local<v8::Value> vp); 151 CJS_Return DelProperty(CJS_Runtime* pRuntime, const wchar_t* propname); 152 void Initial(CPDFSDK_FormFillEnvironment* pFormFillEnv); 153 154 private: 155 void UpdateGlobalPersistentVariables(); 156 void CommitGlobalPersisitentVariables(CJS_Runtime* pRuntime); 157 void DestroyGlobalPersisitentVariables(); 158 CJS_Return SetGlobalVariables(const ByteString& propname, 159 JS_GlobalDataType nType, 160 double dData, 161 bool bData, 162 const ByteString& sData, 163 v8::Local<v8::Object> pData, 164 bool bDefaultPersistent); 165 void ObjectToArray(CJS_Runtime* pRuntime, 166 v8::Local<v8::Object> pObj, 167 CJS_GlobalVariableArray& array); 168 void PutObjectProperty(v8::Local<v8::Object> obj, CJS_KeyValue* pData); 169 170 std::map<ByteString, std::unique_ptr<JSGlobalData>> m_MapGlobal; 171 WideString m_sFilePath; 172 CJS_GlobalData* m_pGlobalData; 173 CPDFSDK_FormFillEnvironment::ObservedPtr m_pFormFillEnv; 174 }; 175 176 } // namespace 177 178 const JSMethodSpec CJS_Global::MethodSpecs[] = { 179 {"setPersistent", setPersistent_static}}; 180 181 int CJS_Global::ObjDefnID = -1; 182 183 // static 184 void CJS_Global::setPersistent_static( 185 const v8::FunctionCallbackInfo<v8::Value>& info) { 186 JSMethod<JSGlobalAlternate, &JSGlobalAlternate::setPersistent>( 187 "setPersistent", "global", info); 188 } 189 190 // static 191 void CJS_Global::queryprop_static( 192 v8::Local<v8::String> property, 193 const v8::PropertyCallbackInfo<v8::Integer>& info) { 194 JSSpecialPropQuery<JSGlobalAlternate>("global", property, info); 195 } 196 197 // static 198 void CJS_Global::getprop_static( 199 v8::Local<v8::String> property, 200 const v8::PropertyCallbackInfo<v8::Value>& info) { 201 JSSpecialPropGet<JSGlobalAlternate>("global", property, info); 202 } 203 204 // static 205 void CJS_Global::putprop_static( 206 v8::Local<v8::String> property, 207 v8::Local<v8::Value> value, 208 const v8::PropertyCallbackInfo<v8::Value>& info) { 209 JSSpecialPropPut<JSGlobalAlternate>("global", property, value, info); 210 } 211 212 // static 213 void CJS_Global::delprop_static( 214 v8::Local<v8::String> property, 215 const v8::PropertyCallbackInfo<v8::Boolean>& info) { 216 JSSpecialPropDel<JSGlobalAlternate>("global", property, info); 217 } 218 219 // static 220 void CJS_Global::DefineAllProperties(CFXJS_Engine* pEngine) { 221 pEngine->DefineObjAllProperties( 222 ObjDefnID, CJS_Global::queryprop_static, CJS_Global::getprop_static, 223 CJS_Global::putprop_static, CJS_Global::delprop_static); 224 } 225 226 // static 227 void CJS_Global::DefineJSObjects(CFXJS_Engine* pEngine) { 228 ObjDefnID = pEngine->DefineObj("global", FXJSOBJTYPE_STATIC, 229 JSConstructor<CJS_Global, JSGlobalAlternate>, 230 JSDestructor<CJS_Global>); 231 DefineMethods(pEngine, ObjDefnID, MethodSpecs, FX_ArraySize(MethodSpecs)); 232 DefineAllProperties(pEngine); 233 } 234 235 void CJS_Global::InitInstance(IJS_Runtime* pIRuntime) { 236 CJS_Runtime* pRuntime = static_cast<CJS_Runtime*>(pIRuntime); 237 JSGlobalAlternate* pGlobal = 238 static_cast<JSGlobalAlternate*>(GetEmbedObject()); 239 pGlobal->Initial(pRuntime->GetFormFillEnv()); 240 } 241 242 JSGlobalData::JSGlobalData() 243 : nType(JS_GlobalDataType::NUMBER), 244 dData(0), 245 bData(false), 246 sData(""), 247 bPersistent(false), 248 bDeleted(false) {} 249 250 JSGlobalData::~JSGlobalData() { 251 pData.Reset(); 252 } 253 254 JSGlobalAlternate::JSGlobalAlternate(CJS_Object* pJSObject) 255 : CJS_EmbedObj(pJSObject), m_pFormFillEnv(nullptr) {} 256 257 JSGlobalAlternate::~JSGlobalAlternate() { 258 DestroyGlobalPersisitentVariables(); 259 m_pGlobalData->Release(); 260 } 261 262 void JSGlobalAlternate::Initial(CPDFSDK_FormFillEnvironment* pFormFillEnv) { 263 m_pFormFillEnv.Reset(pFormFillEnv); 264 m_pGlobalData = CJS_GlobalData::GetRetainedInstance(pFormFillEnv); 265 UpdateGlobalPersistentVariables(); 266 } 267 268 CJS_Return JSGlobalAlternate::QueryProperty(const wchar_t* propname) { 269 return CJS_Return(WideString(propname) != L"setPersistent"); 270 } 271 272 CJS_Return JSGlobalAlternate::DelProperty(CJS_Runtime* pRuntime, 273 const wchar_t* propname) { 274 auto it = m_MapGlobal.find(ByteString::FromUnicode(propname)); 275 if (it == m_MapGlobal.end()) 276 return CJS_Return(false); 277 278 it->second->bDeleted = true; 279 return CJS_Return(true); 280 } 281 282 CJS_Return JSGlobalAlternate::GetProperty(CJS_Runtime* pRuntime, 283 const wchar_t* propname) { 284 auto it = m_MapGlobal.find(ByteString::FromUnicode(propname)); 285 if (it == m_MapGlobal.end()) 286 return CJS_Return(true); 287 288 JSGlobalData* pData = it->second.get(); 289 if (pData->bDeleted) 290 return CJS_Return(true); 291 292 switch (pData->nType) { 293 case JS_GlobalDataType::NUMBER: 294 return CJS_Return(pRuntime->NewNumber(pData->dData)); 295 case JS_GlobalDataType::BOOLEAN: 296 return CJS_Return(pRuntime->NewBoolean(pData->bData)); 297 case JS_GlobalDataType::STRING: 298 return CJS_Return(pRuntime->NewString( 299 WideString::FromLocal(pData->sData.c_str()).c_str())); 300 case JS_GlobalDataType::OBJECT: 301 return CJS_Return( 302 v8::Local<v8::Object>::New(pRuntime->GetIsolate(), pData->pData)); 303 case JS_GlobalDataType::NULLOBJ: 304 return CJS_Return(pRuntime->NewNull()); 305 default: 306 break; 307 } 308 return CJS_Return(false); 309 } 310 311 CJS_Return JSGlobalAlternate::SetProperty(CJS_Runtime* pRuntime, 312 const wchar_t* propname, 313 v8::Local<v8::Value> vp) { 314 ByteString sPropName = ByteString::FromUnicode(propname); 315 if (vp->IsNumber()) { 316 return SetGlobalVariables(sPropName, JS_GlobalDataType::NUMBER, 317 pRuntime->ToDouble(vp), false, "", 318 v8::Local<v8::Object>(), false); 319 } 320 if (vp->IsBoolean()) { 321 return SetGlobalVariables(sPropName, JS_GlobalDataType::BOOLEAN, 0, 322 pRuntime->ToBoolean(vp), "", 323 v8::Local<v8::Object>(), false); 324 } 325 if (vp->IsString()) { 326 return SetGlobalVariables( 327 sPropName, JS_GlobalDataType::STRING, 0, false, 328 ByteString::FromUnicode(pRuntime->ToWideString(vp)), 329 v8::Local<v8::Object>(), false); 330 } 331 if (vp->IsObject()) { 332 return SetGlobalVariables(sPropName, JS_GlobalDataType::OBJECT, 0, false, 333 "", pRuntime->ToObject(vp), false); 334 } 335 if (vp->IsNull()) { 336 return SetGlobalVariables(sPropName, JS_GlobalDataType::NULLOBJ, 0, false, 337 "", v8::Local<v8::Object>(), false); 338 } 339 if (vp->IsUndefined()) { 340 DelProperty(pRuntime, propname); 341 return CJS_Return(true); 342 } 343 return CJS_Return(false); 344 } 345 346 CJS_Return JSGlobalAlternate::setPersistent( 347 CJS_Runtime* pRuntime, 348 const std::vector<v8::Local<v8::Value>>& params) { 349 if (params.size() != 2) 350 return CJS_Return(JSGetStringFromID(JSMessage::kParamError)); 351 352 auto it = m_MapGlobal.find( 353 ByteString::FromUnicode(pRuntime->ToWideString(params[0]))); 354 if (it == m_MapGlobal.end() || it->second->bDeleted) 355 return CJS_Return(JSGetStringFromID(JSMessage::kGlobalNotFoundError)); 356 357 it->second->bPersistent = pRuntime->ToBoolean(params[1]); 358 return CJS_Return(true); 359 } 360 361 void JSGlobalAlternate::UpdateGlobalPersistentVariables() { 362 CJS_Runtime* pRuntime = 363 static_cast<CJS_Runtime*>(CFXJS_Engine::CurrentEngineFromIsolate( 364 m_pJSObject->ToV8Object()->GetIsolate())); 365 366 for (int i = 0, sz = m_pGlobalData->GetSize(); i < sz; i++) { 367 CJS_GlobalData_Element* pData = m_pGlobalData->GetAt(i); 368 switch (pData->data.nType) { 369 case JS_GlobalDataType::NUMBER: 370 SetGlobalVariables(pData->data.sKey, JS_GlobalDataType::NUMBER, 371 pData->data.dData, false, "", 372 v8::Local<v8::Object>(), pData->bPersistent == 1); 373 pRuntime->PutObjectProperty(m_pJSObject->ToV8Object(), 374 pData->data.sKey.UTF8Decode(), 375 pRuntime->NewNumber(pData->data.dData)); 376 break; 377 case JS_GlobalDataType::BOOLEAN: 378 SetGlobalVariables(pData->data.sKey, JS_GlobalDataType::BOOLEAN, 0, 379 pData->data.bData == 1, "", v8::Local<v8::Object>(), 380 pData->bPersistent == 1); 381 pRuntime->PutObjectProperty( 382 m_pJSObject->ToV8Object(), pData->data.sKey.UTF8Decode(), 383 pRuntime->NewBoolean(pData->data.bData == 1)); 384 break; 385 case JS_GlobalDataType::STRING: 386 SetGlobalVariables(pData->data.sKey, JS_GlobalDataType::STRING, 0, 387 false, pData->data.sData, v8::Local<v8::Object>(), 388 pData->bPersistent == 1); 389 pRuntime->PutObjectProperty( 390 m_pJSObject->ToV8Object(), pData->data.sKey.UTF8Decode(), 391 pRuntime->NewString(pData->data.sData.UTF8Decode().AsStringView())); 392 break; 393 case JS_GlobalDataType::OBJECT: { 394 v8::Local<v8::Object> pObj = pRuntime->NewFxDynamicObj(-1); 395 if (!pObj.IsEmpty()) { 396 PutObjectProperty(pObj, &pData->data); 397 SetGlobalVariables(pData->data.sKey, JS_GlobalDataType::OBJECT, 0, 398 false, "", pObj, pData->bPersistent == 1); 399 pRuntime->PutObjectProperty(m_pJSObject->ToV8Object(), 400 pData->data.sKey.UTF8Decode(), pObj); 401 } 402 } break; 403 case JS_GlobalDataType::NULLOBJ: 404 SetGlobalVariables(pData->data.sKey, JS_GlobalDataType::NULLOBJ, 0, 405 false, "", v8::Local<v8::Object>(), 406 pData->bPersistent == 1); 407 pRuntime->PutObjectProperty(m_pJSObject->ToV8Object(), 408 pData->data.sKey.UTF8Decode(), 409 pRuntime->NewNull()); 410 break; 411 } 412 } 413 } 414 415 void JSGlobalAlternate::CommitGlobalPersisitentVariables( 416 CJS_Runtime* pRuntime) { 417 for (const auto& iter : m_MapGlobal) { 418 ByteString name = iter.first; 419 JSGlobalData* pData = iter.second.get(); 420 if (pData->bDeleted) { 421 m_pGlobalData->DeleteGlobalVariable(name); 422 continue; 423 } 424 switch (pData->nType) { 425 case JS_GlobalDataType::NUMBER: 426 m_pGlobalData->SetGlobalVariableNumber(name, pData->dData); 427 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent); 428 break; 429 case JS_GlobalDataType::BOOLEAN: 430 m_pGlobalData->SetGlobalVariableBoolean(name, pData->bData); 431 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent); 432 break; 433 case JS_GlobalDataType::STRING: 434 m_pGlobalData->SetGlobalVariableString(name, pData->sData); 435 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent); 436 break; 437 case JS_GlobalDataType::OBJECT: { 438 CJS_GlobalVariableArray array; 439 v8::Local<v8::Object> obj = v8::Local<v8::Object>::New( 440 GetJSObject()->GetIsolate(), pData->pData); 441 ObjectToArray(pRuntime, obj, array); 442 m_pGlobalData->SetGlobalVariableObject(name, array); 443 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent); 444 } break; 445 case JS_GlobalDataType::NULLOBJ: 446 m_pGlobalData->SetGlobalVariableNull(name); 447 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent); 448 break; 449 } 450 } 451 } 452 453 void JSGlobalAlternate::ObjectToArray(CJS_Runtime* pRuntime, 454 v8::Local<v8::Object> pObj, 455 CJS_GlobalVariableArray& array) { 456 std::vector<WideString> pKeyList = pRuntime->GetObjectPropertyNames(pObj); 457 for (const auto& ws : pKeyList) { 458 ByteString sKey = ws.UTF8Encode(); 459 v8::Local<v8::Value> v = pRuntime->GetObjectProperty(pObj, ws); 460 if (v->IsNumber()) { 461 CJS_KeyValue* pObjElement = new CJS_KeyValue; 462 pObjElement->nType = JS_GlobalDataType::NUMBER; 463 pObjElement->sKey = sKey; 464 pObjElement->dData = pRuntime->ToDouble(v); 465 array.Add(pObjElement); 466 continue; 467 } 468 if (v->IsBoolean()) { 469 CJS_KeyValue* pObjElement = new CJS_KeyValue; 470 pObjElement->nType = JS_GlobalDataType::BOOLEAN; 471 pObjElement->sKey = sKey; 472 pObjElement->dData = pRuntime->ToBoolean(v); 473 array.Add(pObjElement); 474 continue; 475 } 476 if (v->IsString()) { 477 ByteString sValue = ByteString::FromUnicode(pRuntime->ToWideString(v)); 478 CJS_KeyValue* pObjElement = new CJS_KeyValue; 479 pObjElement->nType = JS_GlobalDataType::STRING; 480 pObjElement->sKey = sKey; 481 pObjElement->sData = sValue; 482 array.Add(pObjElement); 483 continue; 484 } 485 if (v->IsObject()) { 486 CJS_KeyValue* pObjElement = new CJS_KeyValue; 487 pObjElement->nType = JS_GlobalDataType::OBJECT; 488 pObjElement->sKey = sKey; 489 ObjectToArray(pRuntime, pRuntime->ToObject(v), pObjElement->objData); 490 array.Add(pObjElement); 491 continue; 492 } 493 if (v->IsNull()) { 494 CJS_KeyValue* pObjElement = new CJS_KeyValue; 495 pObjElement->nType = JS_GlobalDataType::NULLOBJ; 496 pObjElement->sKey = sKey; 497 array.Add(pObjElement); 498 } 499 } 500 } 501 502 void JSGlobalAlternate::PutObjectProperty(v8::Local<v8::Object> pObj, 503 CJS_KeyValue* pData) { 504 CJS_Runtime* pRuntime = CJS_Runtime::CurrentRuntimeFromIsolate( 505 m_pJSObject->ToV8Object()->GetIsolate()); 506 507 for (int i = 0, sz = pData->objData.Count(); i < sz; i++) { 508 CJS_KeyValue* pObjData = pData->objData.GetAt(i); 509 switch (pObjData->nType) { 510 case JS_GlobalDataType::NUMBER: 511 pRuntime->PutObjectProperty(pObj, pObjData->sKey.UTF8Decode(), 512 pRuntime->NewNumber(pObjData->dData)); 513 break; 514 case JS_GlobalDataType::BOOLEAN: 515 pRuntime->PutObjectProperty(pObj, pObjData->sKey.UTF8Decode(), 516 pRuntime->NewBoolean(pObjData->bData == 1)); 517 break; 518 case JS_GlobalDataType::STRING: 519 pRuntime->PutObjectProperty( 520 pObj, pObjData->sKey.UTF8Decode(), 521 pRuntime->NewString(pObjData->sData.UTF8Decode().AsStringView())); 522 break; 523 case JS_GlobalDataType::OBJECT: { 524 v8::Local<v8::Object> pNewObj = pRuntime->NewFxDynamicObj(-1); 525 if (!pNewObj.IsEmpty()) { 526 PutObjectProperty(pNewObj, pObjData); 527 pRuntime->PutObjectProperty(pObj, pObjData->sKey.UTF8Decode(), 528 pNewObj); 529 } 530 } break; 531 case JS_GlobalDataType::NULLOBJ: 532 pRuntime->PutObjectProperty(pObj, pObjData->sKey.UTF8Decode(), 533 pRuntime->NewNull()); 534 break; 535 } 536 } 537 } 538 539 void JSGlobalAlternate::DestroyGlobalPersisitentVariables() { 540 m_MapGlobal.clear(); 541 } 542 543 CJS_Return JSGlobalAlternate::SetGlobalVariables(const ByteString& propname, 544 JS_GlobalDataType nType, 545 double dData, 546 bool bData, 547 const ByteString& sData, 548 v8::Local<v8::Object> pData, 549 bool bDefaultPersistent) { 550 if (propname.IsEmpty()) 551 return CJS_Return(false); 552 553 auto it = m_MapGlobal.find(propname); 554 if (it != m_MapGlobal.end()) { 555 JSGlobalData* pTemp = it->second.get(); 556 if (pTemp->bDeleted || pTemp->nType != nType) { 557 pTemp->dData = 0; 558 pTemp->bData = 0; 559 pTemp->sData.clear(); 560 pTemp->nType = nType; 561 } 562 pTemp->bDeleted = false; 563 switch (nType) { 564 case JS_GlobalDataType::NUMBER: 565 pTemp->dData = dData; 566 break; 567 case JS_GlobalDataType::BOOLEAN: 568 pTemp->bData = bData; 569 break; 570 case JS_GlobalDataType::STRING: 571 pTemp->sData = sData; 572 break; 573 case JS_GlobalDataType::OBJECT: 574 pTemp->pData.Reset(pData->GetIsolate(), pData); 575 break; 576 case JS_GlobalDataType::NULLOBJ: 577 break; 578 default: 579 return CJS_Return(false); 580 } 581 return CJS_Return(true); 582 } 583 584 auto pNewData = pdfium::MakeUnique<JSGlobalData>(); 585 switch (nType) { 586 case JS_GlobalDataType::NUMBER: 587 pNewData->nType = JS_GlobalDataType::NUMBER; 588 pNewData->dData = dData; 589 pNewData->bPersistent = bDefaultPersistent; 590 break; 591 case JS_GlobalDataType::BOOLEAN: 592 pNewData->nType = JS_GlobalDataType::BOOLEAN; 593 pNewData->bData = bData; 594 pNewData->bPersistent = bDefaultPersistent; 595 break; 596 case JS_GlobalDataType::STRING: 597 pNewData->nType = JS_GlobalDataType::STRING; 598 pNewData->sData = sData; 599 pNewData->bPersistent = bDefaultPersistent; 600 break; 601 case JS_GlobalDataType::OBJECT: 602 pNewData->nType = JS_GlobalDataType::OBJECT; 603 pNewData->pData.Reset(pData->GetIsolate(), pData); 604 pNewData->bPersistent = bDefaultPersistent; 605 break; 606 case JS_GlobalDataType::NULLOBJ: 607 pNewData->nType = JS_GlobalDataType::NULLOBJ; 608 pNewData->bPersistent = bDefaultPersistent; 609 break; 610 default: 611 return CJS_Return(false); 612 } 613 m_MapGlobal[propname] = std::move(pNewData); 614 return CJS_Return(true); 615 } 616