blob: 14202646c55d7738133ce0b00a5226219f26a6a7 [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_GlobalData.h"
Tom Sepez37458412015-10-06 11:33:46 -07008
Dan Sinclair85c8e7f2016-11-21 13:50:32 -05009#include <utility>
10
dsinclairb1469a22016-09-29 10:00:05 -070011#include "core/fdrm/crypto/fx_crypt.h"
Dan Sinclair0bb13332017-03-30 16:12:02 -040012#include "third_party/base/ptr_util.h"
tsepez41a53ad2016-03-28 16:59:30 -070013#include "third_party/base/stl_util.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070014
Nico Weber9d8ec5a2015-08-04 13:00:21 -070015#define JS_MAXGLOBALDATA (1024 * 4 - 8)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070016
Nico Weber9d8ec5a2015-08-04 13:00:21 -070017#define READER_JS_GLOBALDATA_FILENAME L"Reader_JsGlobal.Data"
18#define PHANTOM_JS_GLOBALDATA_FILENAME L"Phantom_JsGlobal.Data"
19#define SDK_JS_GLOBALDATA_FILENAME L"SDK_JsGlobal.Data"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070020
weili47228ac2016-07-20 10:35:31 -070021namespace {
22
23const uint8_t JS_RC4KEY[] = {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070024 0x19, 0xa8, 0xe8, 0x01, 0xf6, 0xa8, 0xb6, 0x4d, 0x82, 0x04, 0x45, 0x6d,
25 0xb4, 0xcf, 0xd7, 0x77, 0x67, 0xf9, 0x75, 0x9f, 0xf0, 0xe0, 0x1e, 0x51,
26 0xee, 0x46, 0xfd, 0x0b, 0xc9, 0x93, 0x25, 0x55, 0x4a, 0xee, 0xe0, 0x16,
27 0xd0, 0xdf, 0x8c, 0xfa, 0x2a, 0xa9, 0x49, 0xfd, 0x97, 0x1c, 0x0e, 0x22,
28 0x13, 0x28, 0x7c, 0xaf, 0xc4, 0xfc, 0x9c, 0x12, 0x65, 0x8c, 0x4e, 0x5b,
29 0x04, 0x75, 0x89, 0xc9, 0xb1, 0xed, 0x50, 0xca, 0x96, 0x6f, 0x1a, 0x7a,
30 0xfe, 0x58, 0x5d, 0xec, 0x19, 0x4a, 0xf6, 0x35, 0x6a, 0x97, 0x14, 0x00,
31 0x0e, 0xd0, 0x6b, 0xbb, 0xd5, 0x75, 0x55, 0x8b, 0x6e, 0x6b, 0x19, 0xa0,
32 0xf8, 0x77, 0xd5, 0xa3};
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070033
tsepez41a53ad2016-03-28 16:59:30 -070034// Returns true if non-empty, setting sPropName
weili47228ac2016-07-20 10:35:31 -070035bool TrimPropName(CFX_ByteString* sPropName) {
tsepez41a53ad2016-03-28 16:59:30 -070036 sPropName->TrimLeft();
37 sPropName->TrimRight();
38 return sPropName->GetLength() != 0;
39}
40
weili47228ac2016-07-20 10:35:31 -070041CJS_GlobalData* g_pInstance = nullptr;
42
43} // namespace
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070044
Tom Sepezf4583622015-09-14 15:06:53 -070045// static
dsinclair735606d2016-10-05 15:47:02 -070046CJS_GlobalData* CJS_GlobalData::GetRetainedInstance(
47 CPDFSDK_FormFillEnvironment* pApp) {
weili47228ac2016-07-20 10:35:31 -070048 if (!g_pInstance) {
49 g_pInstance = new CJS_GlobalData();
Tom Sepezf4583622015-09-14 15:06:53 -070050 }
weili47228ac2016-07-20 10:35:31 -070051 ++g_pInstance->m_RefCount;
52 return g_pInstance;
Tom Sepezf4583622015-09-14 15:06:53 -070053}
54
55void CJS_GlobalData::Release() {
56 if (!--m_RefCount) {
weili47228ac2016-07-20 10:35:31 -070057 delete g_pInstance;
58 g_pInstance = nullptr;
Tom Sepezf4583622015-09-14 15:06:53 -070059 }
60}
61
tsepez41a53ad2016-03-28 16:59:30 -070062CJS_GlobalData::CJS_GlobalData()
63 : m_RefCount(0), m_sFilePath(SDK_JS_GLOBALDATA_FILENAME) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070064 LoadGlobalPersistentVariables();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070065}
66
Nico Weber9d8ec5a2015-08-04 13:00:21 -070067CJS_GlobalData::~CJS_GlobalData() {
68 SaveGlobalPersisitentVariables();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070069}
70
tsepez41a53ad2016-03-28 16:59:30 -070071CJS_GlobalData::iterator CJS_GlobalData::FindGlobalVariable(
tsepez24a48882016-04-11 15:18:40 -070072 const CFX_ByteString& propname) {
tsepez41a53ad2016-03-28 16:59:30 -070073 for (auto it = m_arrayGlobalData.begin(); it != m_arrayGlobalData.end();
74 ++it) {
75 if ((*it)->data.sKey == propname)
76 return it;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070077 }
tsepez41a53ad2016-03-28 16:59:30 -070078 return m_arrayGlobalData.end();
79}
80
81CJS_GlobalData::const_iterator CJS_GlobalData::FindGlobalVariable(
tsepez24a48882016-04-11 15:18:40 -070082 const CFX_ByteString& propname) const {
tsepez41a53ad2016-03-28 16:59:30 -070083 for (auto it = m_arrayGlobalData.begin(); it != m_arrayGlobalData.end();
84 ++it) {
85 if ((*it)->data.sKey == propname)
86 return it;
87 }
88 return m_arrayGlobalData.end();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070089}
90
91CJS_GlobalData_Element* CJS_GlobalData::GetGlobalVariable(
tsepez24a48882016-04-11 15:18:40 -070092 const CFX_ByteString& propname) {
tsepez41a53ad2016-03-28 16:59:30 -070093 auto iter = FindGlobalVariable(propname);
94 return iter != m_arrayGlobalData.end() ? iter->get() : nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070095}
96
tsepez24a48882016-04-11 15:18:40 -070097void CJS_GlobalData::SetGlobalVariableNumber(const CFX_ByteString& propname,
Nico Weber9d8ec5a2015-08-04 13:00:21 -070098 double dData) {
tsepez24a48882016-04-11 15:18:40 -070099 CFX_ByteString sPropName(propname);
100 if (!TrimPropName(&sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700101 return;
102
103 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
weili47228ac2016-07-20 10:35:31 -0700104 pData->data.nType = JS_GlobalDataType::NUMBER;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700105 pData->data.dData = dData;
tsepez41a53ad2016-03-28 16:59:30 -0700106 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700107 }
Dan Sinclair0bb13332017-03-30 16:12:02 -0400108 auto pNewData = pdfium::MakeUnique<CJS_GlobalData_Element>();
tsepez41a53ad2016-03-28 16:59:30 -0700109 pNewData->data.sKey = sPropName;
weili47228ac2016-07-20 10:35:31 -0700110 pNewData->data.nType = JS_GlobalDataType::NUMBER;
tsepez41a53ad2016-03-28 16:59:30 -0700111 pNewData->data.dData = dData;
112 m_arrayGlobalData.push_back(std::move(pNewData));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700113}
114
tsepez24a48882016-04-11 15:18:40 -0700115void CJS_GlobalData::SetGlobalVariableBoolean(const CFX_ByteString& propname,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700116 bool bData) {
tsepez24a48882016-04-11 15:18:40 -0700117 CFX_ByteString sPropName(propname);
118 if (!TrimPropName(&sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700119 return;
120
121 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
weili47228ac2016-07-20 10:35:31 -0700122 pData->data.nType = JS_GlobalDataType::BOOLEAN;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700123 pData->data.bData = bData;
tsepez41a53ad2016-03-28 16:59:30 -0700124 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700125 }
Dan Sinclair0bb13332017-03-30 16:12:02 -0400126 auto pNewData = pdfium::MakeUnique<CJS_GlobalData_Element>();
tsepez41a53ad2016-03-28 16:59:30 -0700127 pNewData->data.sKey = sPropName;
weili47228ac2016-07-20 10:35:31 -0700128 pNewData->data.nType = JS_GlobalDataType::BOOLEAN;
tsepez41a53ad2016-03-28 16:59:30 -0700129 pNewData->data.bData = bData;
130 m_arrayGlobalData.push_back(std::move(pNewData));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700131}
132
tsepez24a48882016-04-11 15:18:40 -0700133void CJS_GlobalData::SetGlobalVariableString(const CFX_ByteString& propname,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700134 const CFX_ByteString& sData) {
tsepez24a48882016-04-11 15:18:40 -0700135 CFX_ByteString sPropName(propname);
136 if (!TrimPropName(&sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700137 return;
138
139 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
weili47228ac2016-07-20 10:35:31 -0700140 pData->data.nType = JS_GlobalDataType::STRING;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700141 pData->data.sData = sData;
tsepez41a53ad2016-03-28 16:59:30 -0700142 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700143 }
Dan Sinclair0bb13332017-03-30 16:12:02 -0400144 auto pNewData = pdfium::MakeUnique<CJS_GlobalData_Element>();
tsepez41a53ad2016-03-28 16:59:30 -0700145 pNewData->data.sKey = sPropName;
weili47228ac2016-07-20 10:35:31 -0700146 pNewData->data.nType = JS_GlobalDataType::STRING;
tsepez41a53ad2016-03-28 16:59:30 -0700147 pNewData->data.sData = sData;
148 m_arrayGlobalData.push_back(std::move(pNewData));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700149}
150
151void CJS_GlobalData::SetGlobalVariableObject(
tsepez24a48882016-04-11 15:18:40 -0700152 const CFX_ByteString& propname,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700153 const CJS_GlobalVariableArray& array) {
tsepez24a48882016-04-11 15:18:40 -0700154 CFX_ByteString sPropName(propname);
155 if (!TrimPropName(&sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700156 return;
157
158 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
weili47228ac2016-07-20 10:35:31 -0700159 pData->data.nType = JS_GlobalDataType::OBJECT;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700160 pData->data.objData.Copy(array);
tsepez41a53ad2016-03-28 16:59:30 -0700161 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700162 }
Dan Sinclair0bb13332017-03-30 16:12:02 -0400163 auto pNewData = pdfium::MakeUnique<CJS_GlobalData_Element>();
tsepez41a53ad2016-03-28 16:59:30 -0700164 pNewData->data.sKey = sPropName;
weili47228ac2016-07-20 10:35:31 -0700165 pNewData->data.nType = JS_GlobalDataType::OBJECT;
tsepez41a53ad2016-03-28 16:59:30 -0700166 pNewData->data.objData.Copy(array);
167 m_arrayGlobalData.push_back(std::move(pNewData));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700168}
169
tsepez24a48882016-04-11 15:18:40 -0700170void CJS_GlobalData::SetGlobalVariableNull(const CFX_ByteString& propname) {
171 CFX_ByteString sPropName(propname);
172 if (!TrimPropName(&sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700173 return;
174
175 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
weili47228ac2016-07-20 10:35:31 -0700176 pData->data.nType = JS_GlobalDataType::NULLOBJ;
tsepez41a53ad2016-03-28 16:59:30 -0700177 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700178 }
Dan Sinclair0bb13332017-03-30 16:12:02 -0400179 auto pNewData = pdfium::MakeUnique<CJS_GlobalData_Element>();
tsepez41a53ad2016-03-28 16:59:30 -0700180 pNewData->data.sKey = sPropName;
weili47228ac2016-07-20 10:35:31 -0700181 pNewData->data.nType = JS_GlobalDataType::NULLOBJ;
tsepez41a53ad2016-03-28 16:59:30 -0700182 m_arrayGlobalData.push_back(std::move(pNewData));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700183}
184
tsepez4cf55152016-11-02 14:37:54 -0700185bool CJS_GlobalData::SetGlobalVariablePersistent(const CFX_ByteString& propname,
186 bool bPersistent) {
tsepez24a48882016-04-11 15:18:40 -0700187 CFX_ByteString sPropName(propname);
188 if (!TrimPropName(&sPropName))
tsepez4cf55152016-11-02 14:37:54 -0700189 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700190
tsepez41a53ad2016-03-28 16:59:30 -0700191 CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName);
192 if (!pData)
tsepez4cf55152016-11-02 14:37:54 -0700193 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700194
tsepez41a53ad2016-03-28 16:59:30 -0700195 pData->bPersistent = bPersistent;
tsepez4cf55152016-11-02 14:37:54 -0700196 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700197}
198
tsepez4cf55152016-11-02 14:37:54 -0700199bool CJS_GlobalData::DeleteGlobalVariable(const CFX_ByteString& propname) {
tsepez24a48882016-04-11 15:18:40 -0700200 CFX_ByteString sPropName(propname);
201 if (!TrimPropName(&sPropName))
tsepez4cf55152016-11-02 14:37:54 -0700202 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700203
tsepez41a53ad2016-03-28 16:59:30 -0700204 auto iter = FindGlobalVariable(sPropName);
205 if (iter == m_arrayGlobalData.end())
tsepez4cf55152016-11-02 14:37:54 -0700206 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700207
tsepez41a53ad2016-03-28 16:59:30 -0700208 m_arrayGlobalData.erase(iter);
tsepez4cf55152016-11-02 14:37:54 -0700209 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700210}
211
212int32_t CJS_GlobalData::GetSize() const {
tsepez41a53ad2016-03-28 16:59:30 -0700213 return pdfium::CollectionSize<int32_t>(m_arrayGlobalData);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700214}
215
216CJS_GlobalData_Element* CJS_GlobalData::GetAt(int index) const {
tsepez41a53ad2016-03-28 16:59:30 -0700217 if (index < 0 || index >= GetSize())
218 return nullptr;
219 return m_arrayGlobalData[index].get();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700220}
221
222void CJS_GlobalData::LoadGlobalPersistentVariables() {
thestig1cd352e2016-06-07 17:53:06 -0700223 uint8_t* pBuffer = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700224 int32_t nLength = 0;
225
226 LoadFileBuffer(m_sFilePath.c_str(), pBuffer, nLength);
227 CRYPT_ArcFourCryptBlock(pBuffer, nLength, JS_RC4KEY, sizeof(JS_RC4KEY));
228
229 if (pBuffer) {
230 uint8_t* p = pBuffer;
Tom Sepez62a70f92016-03-21 15:00:20 -0700231 uint16_t wType = *((uint16_t*)p);
232 p += sizeof(uint16_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700233
Tom Sepez62a70f92016-03-21 15:00:20 -0700234 if (wType == (uint16_t)(('X' << 8) | 'F')) {
235 uint16_t wVersion = *((uint16_t*)p);
236 p += sizeof(uint16_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700237
238 ASSERT(wVersion <= 2);
239
tsepezc3255f52016-03-25 14:52:27 -0700240 uint32_t dwCount = *((uint32_t*)p);
241 p += sizeof(uint32_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700242
tsepezc3255f52016-03-25 14:52:27 -0700243 uint32_t dwSize = *((uint32_t*)p);
244 p += sizeof(uint32_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700245
tsepezc3255f52016-03-25 14:52:27 -0700246 if (dwSize == nLength - sizeof(uint16_t) * 2 - sizeof(uint32_t) * 2) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700247 for (int32_t i = 0, sz = dwCount; i < sz; i++) {
248 if (p > pBuffer + nLength)
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700249 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700250
tsepezc3255f52016-03-25 14:52:27 -0700251 uint32_t dwNameLen = *((uint32_t*)p);
252 p += sizeof(uint32_t);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700253
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700254 if (p + dwNameLen > pBuffer + nLength)
255 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700256
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700257 CFX_ByteString sEntry = CFX_ByteString(p, dwNameLen);
258 p += sizeof(char) * dwNameLen;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700259
weili47228ac2016-07-20 10:35:31 -0700260 JS_GlobalDataType wDataType =
261 static_cast<JS_GlobalDataType>(*((uint16_t*)p));
Tom Sepez62a70f92016-03-21 15:00:20 -0700262 p += sizeof(uint16_t);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700263
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700264 switch (wDataType) {
weili47228ac2016-07-20 10:35:31 -0700265 case JS_GlobalDataType::NUMBER: {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700266 double dData = 0;
267 switch (wVersion) {
268 case 1: {
tsepezc3255f52016-03-25 14:52:27 -0700269 uint32_t dwData = *((uint32_t*)p);
270 p += sizeof(uint32_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700271 dData = dwData;
272 } break;
273 case 2: {
274 dData = *((double*)p);
275 p += sizeof(double);
276 } break;
277 }
278 SetGlobalVariableNumber(sEntry, dData);
tsepez4cf55152016-11-02 14:37:54 -0700279 SetGlobalVariablePersistent(sEntry, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700280 } break;
weili47228ac2016-07-20 10:35:31 -0700281 case JS_GlobalDataType::BOOLEAN: {
Tom Sepez62a70f92016-03-21 15:00:20 -0700282 uint16_t wData = *((uint16_t*)p);
283 p += sizeof(uint16_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700284 SetGlobalVariableBoolean(sEntry, (bool)(wData == 1));
tsepez4cf55152016-11-02 14:37:54 -0700285 SetGlobalVariablePersistent(sEntry, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700286 } break;
weili47228ac2016-07-20 10:35:31 -0700287 case JS_GlobalDataType::STRING: {
tsepezc3255f52016-03-25 14:52:27 -0700288 uint32_t dwLength = *((uint32_t*)p);
289 p += sizeof(uint32_t);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700290
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700291 if (p + dwLength > pBuffer + nLength)
292 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700293
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700294 SetGlobalVariableString(sEntry, CFX_ByteString(p, dwLength));
tsepez4cf55152016-11-02 14:37:54 -0700295 SetGlobalVariablePersistent(sEntry, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700296 p += sizeof(char) * dwLength;
297 } break;
weili47228ac2016-07-20 10:35:31 -0700298 case JS_GlobalDataType::NULLOBJ: {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700299 SetGlobalVariableNull(sEntry);
tsepez4cf55152016-11-02 14:37:54 -0700300 SetGlobalVariablePersistent(sEntry, true);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700301 }
weili47228ac2016-07-20 10:35:31 -0700302 case JS_GlobalDataType::OBJECT:
303 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700304 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700305 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700306 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700307 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700308 FX_Free(pBuffer);
309 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700310}
311
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700312void CJS_GlobalData::SaveGlobalPersisitentVariables() {
tsepezc3255f52016-03-25 14:52:27 -0700313 uint32_t nCount = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700314 CFX_BinaryBuf sData;
tsepez41a53ad2016-03-28 16:59:30 -0700315 for (const auto& pElement : m_arrayGlobalData) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700316 if (pElement->bPersistent) {
317 CFX_BinaryBuf sElement;
318 MakeByteString(pElement->data.sKey, &pElement->data, sElement);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700319 if (sData.GetSize() + sElement.GetSize() > JS_MAXGLOBALDATA)
320 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700321
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700322 sData.AppendBlock(sElement.GetBuffer(), sElement.GetSize());
323 nCount++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700324 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700325 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700326
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700327 CFX_BinaryBuf sFile;
Tom Sepez62a70f92016-03-21 15:00:20 -0700328 uint16_t wType = (uint16_t)(('X' << 8) | 'F');
329 sFile.AppendBlock(&wType, sizeof(uint16_t));
330 uint16_t wVersion = 2;
331 sFile.AppendBlock(&wVersion, sizeof(uint16_t));
tsepezc3255f52016-03-25 14:52:27 -0700332 sFile.AppendBlock(&nCount, sizeof(uint32_t));
333 uint32_t dwSize = sData.GetSize();
334 sFile.AppendBlock(&dwSize, sizeof(uint32_t));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700335
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700336 sFile.AppendBlock(sData.GetBuffer(), sData.GetSize());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700337
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700338 CRYPT_ArcFourCryptBlock(sFile.GetBuffer(), sFile.GetSize(), JS_RC4KEY,
339 sizeof(JS_RC4KEY));
Dan Sinclair812e96c2017-03-13 16:43:37 -0400340 WriteFileBuffer(m_sFilePath.c_str(), (const char*)sFile.GetBuffer(),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700341 sFile.GetSize());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700342}
343
Dan Sinclair812e96c2017-03-13 16:43:37 -0400344void CJS_GlobalData::LoadFileBuffer(const wchar_t* sFilePath,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700345 uint8_t*& pBuffer,
346 int32_t& nLength) {
347 // UnSupport.
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700348}
349
Dan Sinclair812e96c2017-03-13 16:43:37 -0400350void CJS_GlobalData::WriteFileBuffer(const wchar_t* sFilePath,
351 const char* pBuffer,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700352 int32_t nLength) {
353 // UnSupport.
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700354}
355
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700356void CJS_GlobalData::MakeByteString(const CFX_ByteString& name,
357 CJS_KeyValue* pData,
358 CFX_BinaryBuf& sData) {
weili47228ac2016-07-20 10:35:31 -0700359 switch (pData->nType) {
360 case JS_GlobalDataType::NUMBER: {
tsepezc3255f52016-03-25 14:52:27 -0700361 uint32_t dwNameLen = (uint32_t)name.GetLength();
362 sData.AppendBlock(&dwNameLen, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700363 sData.AppendString(name);
weili47228ac2016-07-20 10:35:31 -0700364 sData.AppendBlock(&pData->nType, sizeof(uint16_t));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700365
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700366 double dData = pData->dData;
367 sData.AppendBlock(&dData, sizeof(double));
368 } break;
weili47228ac2016-07-20 10:35:31 -0700369 case JS_GlobalDataType::BOOLEAN: {
tsepezc3255f52016-03-25 14:52:27 -0700370 uint32_t dwNameLen = (uint32_t)name.GetLength();
371 sData.AppendBlock(&dwNameLen, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700372 sData.AppendString(name);
weili47228ac2016-07-20 10:35:31 -0700373 sData.AppendBlock(&pData->nType, sizeof(uint16_t));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700374
Tom Sepez62a70f92016-03-21 15:00:20 -0700375 uint16_t wData = (uint16_t)pData->bData;
376 sData.AppendBlock(&wData, sizeof(uint16_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700377 } break;
weili47228ac2016-07-20 10:35:31 -0700378 case JS_GlobalDataType::STRING: {
tsepezc3255f52016-03-25 14:52:27 -0700379 uint32_t dwNameLen = (uint32_t)name.GetLength();
380 sData.AppendBlock(&dwNameLen, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700381 sData.AppendString(name);
weili47228ac2016-07-20 10:35:31 -0700382 sData.AppendBlock(&pData->nType, sizeof(uint16_t));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700383
tsepezc3255f52016-03-25 14:52:27 -0700384 uint32_t dwDataLen = (uint32_t)pData->sData.GetLength();
385 sData.AppendBlock(&dwDataLen, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700386 sData.AppendString(pData->sData);
387 } break;
weili47228ac2016-07-20 10:35:31 -0700388 case JS_GlobalDataType::NULLOBJ: {
tsepezc3255f52016-03-25 14:52:27 -0700389 uint32_t dwNameLen = (uint32_t)name.GetLength();
390 sData.AppendBlock(&dwNameLen, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700391 sData.AppendString(name);
weili47228ac2016-07-20 10:35:31 -0700392 sData.AppendBlock(&pData->nType, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700393 } break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700394 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700395 break;
396 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700397}