blob: fe3475c2b1ebe4bbcc95b750974795aa0e33e456 [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 Sinclair13ee55a2016-03-14 15:56:00 -04009#include "core/fdrm/crypto/include/fx_crypt.h"
tsepez41a53ad2016-03-28 16:59:30 -070010#include "third_party/base/stl_util.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070011
Nico Weber9d8ec5a2015-08-04 13:00:21 -070012#define JS_MAXGLOBALDATA (1024 * 4 - 8)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070013
Nico Weber9d8ec5a2015-08-04 13:00:21 -070014CJS_GlobalVariableArray::CJS_GlobalVariableArray() {}
15
16CJS_GlobalVariableArray::~CJS_GlobalVariableArray() {
17 Empty();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070018}
19
Nico Weber9d8ec5a2015-08-04 13:00:21 -070020void CJS_GlobalVariableArray::Copy(const CJS_GlobalVariableArray& array) {
21 Empty();
22 for (int i = 0, sz = array.Count(); i < sz; i++) {
23 CJS_KeyValue* pOldObjData = array.GetAt(i);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070024 switch (pOldObjData->nType) {
25 case JS_GLOBALDATA_TYPE_NUMBER: {
26 CJS_KeyValue* pNewObjData = new CJS_KeyValue;
27 pNewObjData->sKey = pOldObjData->sKey;
28 pNewObjData->nType = pOldObjData->nType;
29 pNewObjData->dData = pOldObjData->dData;
30 Add(pNewObjData);
31 } break;
32 case JS_GLOBALDATA_TYPE_BOOLEAN: {
33 CJS_KeyValue* pNewObjData = new CJS_KeyValue;
34 pNewObjData->sKey = pOldObjData->sKey;
35 pNewObjData->nType = pOldObjData->nType;
36 pNewObjData->bData = pOldObjData->bData;
37 Add(pNewObjData);
38 } break;
39 case JS_GLOBALDATA_TYPE_STRING: {
40 CJS_KeyValue* pNewObjData = new CJS_KeyValue;
41 pNewObjData->sKey = pOldObjData->sKey;
42 pNewObjData->nType = pOldObjData->nType;
43 pNewObjData->sData = pOldObjData->sData;
44 Add(pNewObjData);
45 } break;
46 case JS_GLOBALDATA_TYPE_OBJECT: {
47 CJS_KeyValue* pNewObjData = new CJS_KeyValue;
48 pNewObjData->sKey = pOldObjData->sKey;
49 pNewObjData->nType = pOldObjData->nType;
50 pNewObjData->objData.Copy(pOldObjData->objData);
51 Add(pNewObjData);
Lei Zhangd77f03f2015-12-28 13:12:26 -080052 } break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070053 case JS_GLOBALDATA_TYPE_NULL: {
54 CJS_KeyValue* pNewObjData = new CJS_KeyValue;
55 pNewObjData->sKey = pOldObjData->sKey;
56 pNewObjData->nType = pOldObjData->nType;
57 Add(pNewObjData);
Lei Zhangd77f03f2015-12-28 13:12:26 -080058 } break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070059 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -070060 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070061}
62
Nico Weber9d8ec5a2015-08-04 13:00:21 -070063void CJS_GlobalVariableArray::Add(CJS_KeyValue* p) {
64 array.Add(p);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070065}
66
Nico Weber9d8ec5a2015-08-04 13:00:21 -070067int CJS_GlobalVariableArray::Count() const {
68 return array.GetSize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070069}
70
Nico Weber9d8ec5a2015-08-04 13:00:21 -070071CJS_KeyValue* CJS_GlobalVariableArray::GetAt(int index) const {
72 return array.GetAt(index);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070073}
74
Nico Weber9d8ec5a2015-08-04 13:00:21 -070075void CJS_GlobalVariableArray::Empty() {
76 for (int i = 0, sz = array.GetSize(); i < sz; i++)
77 delete array.GetAt(i);
78 array.RemoveAll();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070079}
80
Nico Weber9d8ec5a2015-08-04 13:00:21 -070081#define READER_JS_GLOBALDATA_FILENAME L"Reader_JsGlobal.Data"
82#define PHANTOM_JS_GLOBALDATA_FILENAME L"Phantom_JsGlobal.Data"
83#define SDK_JS_GLOBALDATA_FILENAME L"SDK_JsGlobal.Data"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070084
Nico Weber9d8ec5a2015-08-04 13:00:21 -070085static const uint8_t JS_RC4KEY[] = {
86 0x19, 0xa8, 0xe8, 0x01, 0xf6, 0xa8, 0xb6, 0x4d, 0x82, 0x04, 0x45, 0x6d,
87 0xb4, 0xcf, 0xd7, 0x77, 0x67, 0xf9, 0x75, 0x9f, 0xf0, 0xe0, 0x1e, 0x51,
88 0xee, 0x46, 0xfd, 0x0b, 0xc9, 0x93, 0x25, 0x55, 0x4a, 0xee, 0xe0, 0x16,
89 0xd0, 0xdf, 0x8c, 0xfa, 0x2a, 0xa9, 0x49, 0xfd, 0x97, 0x1c, 0x0e, 0x22,
90 0x13, 0x28, 0x7c, 0xaf, 0xc4, 0xfc, 0x9c, 0x12, 0x65, 0x8c, 0x4e, 0x5b,
91 0x04, 0x75, 0x89, 0xc9, 0xb1, 0xed, 0x50, 0xca, 0x96, 0x6f, 0x1a, 0x7a,
92 0xfe, 0x58, 0x5d, 0xec, 0x19, 0x4a, 0xf6, 0x35, 0x6a, 0x97, 0x14, 0x00,
93 0x0e, 0xd0, 0x6b, 0xbb, 0xd5, 0x75, 0x55, 0x8b, 0x6e, 0x6b, 0x19, 0xa0,
94 0xf8, 0x77, 0xd5, 0xa3};
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070095
tsepez41a53ad2016-03-28 16:59:30 -070096// Returns true if non-empty, setting sPropName
97static bool TrimPropName(const char* propname, CFX_ByteString* sPropName) {
98 ASSERT(propname);
99 *sPropName = propname;
100 sPropName->TrimLeft();
101 sPropName->TrimRight();
102 return sPropName->GetLength() != 0;
103}
104
Tom Sepezf4583622015-09-14 15:06:53 -0700105CJS_GlobalData* CJS_GlobalData::g_Instance = nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700106
Tom Sepezf4583622015-09-14 15:06:53 -0700107// static
108CJS_GlobalData* CJS_GlobalData::GetRetainedInstance(CPDFDoc_Environment* pApp) {
109 if (!g_Instance) {
Tom Sepezdfbf8e72015-10-14 14:17:26 -0700110 g_Instance = new CJS_GlobalData();
Tom Sepezf4583622015-09-14 15:06:53 -0700111 }
112 ++g_Instance->m_RefCount;
113 return g_Instance;
114}
115
116void CJS_GlobalData::Release() {
117 if (!--m_RefCount) {
118 delete g_Instance;
119 g_Instance = nullptr;
120 }
121}
122
tsepez41a53ad2016-03-28 16:59:30 -0700123CJS_GlobalData::CJS_GlobalData()
124 : m_RefCount(0), m_sFilePath(SDK_JS_GLOBALDATA_FILENAME) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700125 LoadGlobalPersistentVariables();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700126}
127
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700128CJS_GlobalData::~CJS_GlobalData() {
129 SaveGlobalPersisitentVariables();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700130}
131
tsepez41a53ad2016-03-28 16:59:30 -0700132CJS_GlobalData::iterator CJS_GlobalData::FindGlobalVariable(
133 const FX_CHAR* propname) {
134 for (auto it = m_arrayGlobalData.begin(); it != m_arrayGlobalData.end();
135 ++it) {
136 if ((*it)->data.sKey == propname)
137 return it;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700138 }
tsepez41a53ad2016-03-28 16:59:30 -0700139 return m_arrayGlobalData.end();
140}
141
142CJS_GlobalData::const_iterator CJS_GlobalData::FindGlobalVariable(
143 const FX_CHAR* propname) const {
144 for (auto it = m_arrayGlobalData.begin(); it != m_arrayGlobalData.end();
145 ++it) {
146 if ((*it)->data.sKey == propname)
147 return it;
148 }
149 return m_arrayGlobalData.end();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700150}
151
152CJS_GlobalData_Element* CJS_GlobalData::GetGlobalVariable(
153 const FX_CHAR* propname) {
tsepez41a53ad2016-03-28 16:59:30 -0700154 auto iter = FindGlobalVariable(propname);
155 return iter != m_arrayGlobalData.end() ? iter->get() : nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700156}
157
158void CJS_GlobalData::SetGlobalVariableNumber(const FX_CHAR* propname,
159 double dData) {
tsepez41a53ad2016-03-28 16:59:30 -0700160 CFX_ByteString sPropName;
161 if (!TrimPropName(propname, &sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700162 return;
163
164 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
165 pData->data.nType = JS_GLOBALDATA_TYPE_NUMBER;
166 pData->data.dData = dData;
tsepez41a53ad2016-03-28 16:59:30 -0700167 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700168 }
tsepez41a53ad2016-03-28 16:59:30 -0700169 std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
170 pNewData->data.sKey = sPropName;
171 pNewData->data.nType = JS_GLOBALDATA_TYPE_NUMBER;
172 pNewData->data.dData = dData;
173 m_arrayGlobalData.push_back(std::move(pNewData));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700174}
175
176void CJS_GlobalData::SetGlobalVariableBoolean(const FX_CHAR* propname,
177 bool bData) {
tsepez41a53ad2016-03-28 16:59:30 -0700178 CFX_ByteString sPropName;
179 if (!TrimPropName(propname, &sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700180 return;
181
182 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
183 pData->data.nType = JS_GLOBALDATA_TYPE_BOOLEAN;
184 pData->data.bData = bData;
tsepez41a53ad2016-03-28 16:59:30 -0700185 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700186 }
tsepez41a53ad2016-03-28 16:59:30 -0700187 std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
188 pNewData->data.sKey = sPropName;
189 pNewData->data.nType = JS_GLOBALDATA_TYPE_BOOLEAN;
190 pNewData->data.bData = bData;
191 m_arrayGlobalData.push_back(std::move(pNewData));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700192}
193
194void CJS_GlobalData::SetGlobalVariableString(const FX_CHAR* propname,
195 const CFX_ByteString& sData) {
tsepez41a53ad2016-03-28 16:59:30 -0700196 CFX_ByteString sPropName;
197 if (!TrimPropName(propname, &sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700198 return;
199
200 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
201 pData->data.nType = JS_GLOBALDATA_TYPE_STRING;
202 pData->data.sData = sData;
tsepez41a53ad2016-03-28 16:59:30 -0700203 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700204 }
tsepez41a53ad2016-03-28 16:59:30 -0700205 std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
206 pNewData->data.sKey = sPropName;
207 pNewData->data.nType = JS_GLOBALDATA_TYPE_STRING;
208 pNewData->data.sData = sData;
209 m_arrayGlobalData.push_back(std::move(pNewData));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700210}
211
212void CJS_GlobalData::SetGlobalVariableObject(
213 const FX_CHAR* propname,
214 const CJS_GlobalVariableArray& array) {
tsepez41a53ad2016-03-28 16:59:30 -0700215 CFX_ByteString sPropName;
216 if (!TrimPropName(propname, &sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700217 return;
218
219 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
220 pData->data.nType = JS_GLOBALDATA_TYPE_OBJECT;
221 pData->data.objData.Copy(array);
tsepez41a53ad2016-03-28 16:59:30 -0700222 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700223 }
tsepez41a53ad2016-03-28 16:59:30 -0700224 std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
225 pNewData->data.sKey = sPropName;
226 pNewData->data.nType = JS_GLOBALDATA_TYPE_OBJECT;
227 pNewData->data.objData.Copy(array);
228 m_arrayGlobalData.push_back(std::move(pNewData));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700229}
230
231void CJS_GlobalData::SetGlobalVariableNull(const FX_CHAR* propname) {
tsepez41a53ad2016-03-28 16:59:30 -0700232 CFX_ByteString sPropName;
233 if (!TrimPropName(propname, &sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700234 return;
235
236 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
237 pData->data.nType = JS_GLOBALDATA_TYPE_NULL;
tsepez41a53ad2016-03-28 16:59:30 -0700238 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700239 }
tsepez41a53ad2016-03-28 16:59:30 -0700240 std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
241 pNewData->data.sKey = sPropName;
242 pNewData->data.nType = JS_GLOBALDATA_TYPE_NULL;
243 m_arrayGlobalData.push_back(std::move(pNewData));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700244}
245
246FX_BOOL CJS_GlobalData::SetGlobalVariablePersistent(const FX_CHAR* propname,
247 FX_BOOL bPersistent) {
tsepez41a53ad2016-03-28 16:59:30 -0700248 CFX_ByteString sPropName;
249 if (!TrimPropName(propname, &sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700250 return FALSE;
251
tsepez41a53ad2016-03-28 16:59:30 -0700252 CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName);
253 if (!pData)
254 return FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700255
tsepez41a53ad2016-03-28 16:59:30 -0700256 pData->bPersistent = bPersistent;
257 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700258}
259
260FX_BOOL CJS_GlobalData::DeleteGlobalVariable(const FX_CHAR* propname) {
tsepez41a53ad2016-03-28 16:59:30 -0700261 CFX_ByteString sPropName;
262 if (!TrimPropName(propname, &sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700263 return FALSE;
264
tsepez41a53ad2016-03-28 16:59:30 -0700265 auto iter = FindGlobalVariable(sPropName);
266 if (iter == m_arrayGlobalData.end())
267 return FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700268
tsepez41a53ad2016-03-28 16:59:30 -0700269 m_arrayGlobalData.erase(iter);
270 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700271}
272
273int32_t CJS_GlobalData::GetSize() const {
tsepez41a53ad2016-03-28 16:59:30 -0700274 return pdfium::CollectionSize<int32_t>(m_arrayGlobalData);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700275}
276
277CJS_GlobalData_Element* CJS_GlobalData::GetAt(int index) const {
tsepez41a53ad2016-03-28 16:59:30 -0700278 if (index < 0 || index >= GetSize())
279 return nullptr;
280 return m_arrayGlobalData[index].get();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700281}
282
283void CJS_GlobalData::LoadGlobalPersistentVariables() {
284 uint8_t* pBuffer = NULL;
285 int32_t nLength = 0;
286
287 LoadFileBuffer(m_sFilePath.c_str(), pBuffer, nLength);
288 CRYPT_ArcFourCryptBlock(pBuffer, nLength, JS_RC4KEY, sizeof(JS_RC4KEY));
289
290 if (pBuffer) {
291 uint8_t* p = pBuffer;
Tom Sepez62a70f92016-03-21 15:00:20 -0700292 uint16_t wType = *((uint16_t*)p);
293 p += sizeof(uint16_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700294
Tom Sepez62a70f92016-03-21 15:00:20 -0700295 // uint16_t wTemp = (uint16_t)(('X' << 8) | 'F');
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700296
Tom Sepez62a70f92016-03-21 15:00:20 -0700297 if (wType == (uint16_t)(('X' << 8) | 'F')) {
298 uint16_t wVersion = *((uint16_t*)p);
299 p += sizeof(uint16_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700300
301 ASSERT(wVersion <= 2);
302
tsepezc3255f52016-03-25 14:52:27 -0700303 uint32_t dwCount = *((uint32_t*)p);
304 p += sizeof(uint32_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700305
tsepezc3255f52016-03-25 14:52:27 -0700306 uint32_t dwSize = *((uint32_t*)p);
307 p += sizeof(uint32_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700308
tsepezc3255f52016-03-25 14:52:27 -0700309 if (dwSize == nLength - sizeof(uint16_t) * 2 - sizeof(uint32_t) * 2) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700310 for (int32_t i = 0, sz = dwCount; i < sz; i++) {
311 if (p > pBuffer + nLength)
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700312 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700313
tsepezc3255f52016-03-25 14:52:27 -0700314 uint32_t dwNameLen = *((uint32_t*)p);
315 p += sizeof(uint32_t);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700316
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700317 if (p + dwNameLen > pBuffer + nLength)
318 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700319
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700320 CFX_ByteString sEntry = CFX_ByteString(p, dwNameLen);
321 p += sizeof(char) * dwNameLen;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700322
Tom Sepez62a70f92016-03-21 15:00:20 -0700323 uint16_t wDataType = *((uint16_t*)p);
324 p += sizeof(uint16_t);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700325
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700326 switch (wDataType) {
327 case JS_GLOBALDATA_TYPE_NUMBER: {
328 double dData = 0;
329 switch (wVersion) {
330 case 1: {
tsepezc3255f52016-03-25 14:52:27 -0700331 uint32_t dwData = *((uint32_t*)p);
332 p += sizeof(uint32_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700333 dData = dwData;
334 } break;
335 case 2: {
336 dData = *((double*)p);
337 p += sizeof(double);
338 } break;
339 }
340 SetGlobalVariableNumber(sEntry, dData);
341 SetGlobalVariablePersistent(sEntry, TRUE);
342 } break;
343 case JS_GLOBALDATA_TYPE_BOOLEAN: {
Tom Sepez62a70f92016-03-21 15:00:20 -0700344 uint16_t wData = *((uint16_t*)p);
345 p += sizeof(uint16_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700346 SetGlobalVariableBoolean(sEntry, (bool)(wData == 1));
347 SetGlobalVariablePersistent(sEntry, TRUE);
348 } break;
349 case JS_GLOBALDATA_TYPE_STRING: {
tsepezc3255f52016-03-25 14:52:27 -0700350 uint32_t dwLength = *((uint32_t*)p);
351 p += sizeof(uint32_t);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700352
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700353 if (p + dwLength > pBuffer + nLength)
354 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700355
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700356 SetGlobalVariableString(sEntry, CFX_ByteString(p, dwLength));
357 SetGlobalVariablePersistent(sEntry, TRUE);
358 p += sizeof(char) * dwLength;
359 } break;
360 case JS_GLOBALDATA_TYPE_NULL: {
361 SetGlobalVariableNull(sEntry);
362 SetGlobalVariablePersistent(sEntry, TRUE);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700363 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700364 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700365 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700366 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700367 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700368 FX_Free(pBuffer);
369 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700370}
371
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700372void CJS_GlobalData::SaveGlobalPersisitentVariables() {
tsepezc3255f52016-03-25 14:52:27 -0700373 uint32_t nCount = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700374 CFX_BinaryBuf sData;
tsepez41a53ad2016-03-28 16:59:30 -0700375 for (const auto& pElement : m_arrayGlobalData) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700376 if (pElement->bPersistent) {
377 CFX_BinaryBuf sElement;
378 MakeByteString(pElement->data.sKey, &pElement->data, sElement);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700379 if (sData.GetSize() + sElement.GetSize() > JS_MAXGLOBALDATA)
380 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700381
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700382 sData.AppendBlock(sElement.GetBuffer(), sElement.GetSize());
383 nCount++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700384 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700385 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700386
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700387 CFX_BinaryBuf sFile;
Tom Sepez62a70f92016-03-21 15:00:20 -0700388 uint16_t wType = (uint16_t)(('X' << 8) | 'F');
389 sFile.AppendBlock(&wType, sizeof(uint16_t));
390 uint16_t wVersion = 2;
391 sFile.AppendBlock(&wVersion, sizeof(uint16_t));
tsepezc3255f52016-03-25 14:52:27 -0700392 sFile.AppendBlock(&nCount, sizeof(uint32_t));
393 uint32_t dwSize = sData.GetSize();
394 sFile.AppendBlock(&dwSize, sizeof(uint32_t));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700395
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700396 sFile.AppendBlock(sData.GetBuffer(), sData.GetSize());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700397
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700398 CRYPT_ArcFourCryptBlock(sFile.GetBuffer(), sFile.GetSize(), JS_RC4KEY,
399 sizeof(JS_RC4KEY));
400 WriteFileBuffer(m_sFilePath.c_str(), (const FX_CHAR*)sFile.GetBuffer(),
401 sFile.GetSize());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700402}
403
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700404void CJS_GlobalData::LoadFileBuffer(const FX_WCHAR* sFilePath,
405 uint8_t*& pBuffer,
406 int32_t& nLength) {
407 // UnSupport.
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700408}
409
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700410void CJS_GlobalData::WriteFileBuffer(const FX_WCHAR* sFilePath,
411 const FX_CHAR* pBuffer,
412 int32_t nLength) {
413 // UnSupport.
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700414}
415
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700416void CJS_GlobalData::MakeByteString(const CFX_ByteString& name,
417 CJS_KeyValue* pData,
418 CFX_BinaryBuf& sData) {
Tom Sepez62a70f92016-03-21 15:00:20 -0700419 uint16_t wType = (uint16_t)pData->nType;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700420 switch (wType) {
421 case JS_GLOBALDATA_TYPE_NUMBER: {
tsepezc3255f52016-03-25 14:52:27 -0700422 uint32_t dwNameLen = (uint32_t)name.GetLength();
423 sData.AppendBlock(&dwNameLen, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700424 sData.AppendString(name);
Tom Sepez62a70f92016-03-21 15:00:20 -0700425 sData.AppendBlock(&wType, sizeof(uint16_t));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700426
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700427 double dData = pData->dData;
428 sData.AppendBlock(&dData, sizeof(double));
429 } break;
430 case JS_GLOBALDATA_TYPE_BOOLEAN: {
tsepezc3255f52016-03-25 14:52:27 -0700431 uint32_t dwNameLen = (uint32_t)name.GetLength();
432 sData.AppendBlock(&dwNameLen, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700433 sData.AppendString(name);
Tom Sepez62a70f92016-03-21 15:00:20 -0700434 sData.AppendBlock(&wType, sizeof(uint16_t));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700435
Tom Sepez62a70f92016-03-21 15:00:20 -0700436 uint16_t wData = (uint16_t)pData->bData;
437 sData.AppendBlock(&wData, sizeof(uint16_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700438 } break;
439 case JS_GLOBALDATA_TYPE_STRING: {
tsepezc3255f52016-03-25 14:52:27 -0700440 uint32_t dwNameLen = (uint32_t)name.GetLength();
441 sData.AppendBlock(&dwNameLen, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700442 sData.AppendString(name);
Tom Sepez62a70f92016-03-21 15:00:20 -0700443 sData.AppendBlock(&wType, sizeof(uint16_t));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700444
tsepezc3255f52016-03-25 14:52:27 -0700445 uint32_t dwDataLen = (uint32_t)pData->sData.GetLength();
446 sData.AppendBlock(&dwDataLen, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700447 sData.AppendString(pData->sData);
448 } break;
449 case JS_GLOBALDATA_TYPE_NULL: {
tsepezc3255f52016-03-25 14:52:27 -0700450 uint32_t dwNameLen = (uint32_t)name.GetLength();
451 sData.AppendBlock(&dwNameLen, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700452 sData.AppendString(name);
tsepezc3255f52016-03-25 14:52:27 -0700453 sData.AppendBlock(&wType, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700454 } break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700455 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700456 break;
457 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700458}