blob: 3a9e52175a4144bd5a989a1a475e9adf5bf2c3d3 [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"
Lei Zhangbde53d22015-11-12 22:21:30 -080010#include "fpdfsdk/include/javascript/IJavaScript.h"
tsepez41a53ad2016-03-28 16:59:30 -070011#include "third_party/base/stl_util.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070012
Nico Weber9d8ec5a2015-08-04 13:00:21 -070013#define JS_MAXGLOBALDATA (1024 * 4 - 8)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070014
15/* --------------------- CJS_GlobalVariableArray --------------------- */
16
Nico Weber9d8ec5a2015-08-04 13:00:21 -070017CJS_GlobalVariableArray::CJS_GlobalVariableArray() {}
18
19CJS_GlobalVariableArray::~CJS_GlobalVariableArray() {
20 Empty();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070021}
22
Nico Weber9d8ec5a2015-08-04 13:00:21 -070023void CJS_GlobalVariableArray::Copy(const CJS_GlobalVariableArray& array) {
24 Empty();
25 for (int i = 0, sz = array.Count(); i < sz; i++) {
26 CJS_KeyValue* pOldObjData = array.GetAt(i);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070027 switch (pOldObjData->nType) {
28 case JS_GLOBALDATA_TYPE_NUMBER: {
29 CJS_KeyValue* pNewObjData = new CJS_KeyValue;
30 pNewObjData->sKey = pOldObjData->sKey;
31 pNewObjData->nType = pOldObjData->nType;
32 pNewObjData->dData = pOldObjData->dData;
33 Add(pNewObjData);
34 } break;
35 case JS_GLOBALDATA_TYPE_BOOLEAN: {
36 CJS_KeyValue* pNewObjData = new CJS_KeyValue;
37 pNewObjData->sKey = pOldObjData->sKey;
38 pNewObjData->nType = pOldObjData->nType;
39 pNewObjData->bData = pOldObjData->bData;
40 Add(pNewObjData);
41 } break;
42 case JS_GLOBALDATA_TYPE_STRING: {
43 CJS_KeyValue* pNewObjData = new CJS_KeyValue;
44 pNewObjData->sKey = pOldObjData->sKey;
45 pNewObjData->nType = pOldObjData->nType;
46 pNewObjData->sData = pOldObjData->sData;
47 Add(pNewObjData);
48 } break;
49 case JS_GLOBALDATA_TYPE_OBJECT: {
50 CJS_KeyValue* pNewObjData = new CJS_KeyValue;
51 pNewObjData->sKey = pOldObjData->sKey;
52 pNewObjData->nType = pOldObjData->nType;
53 pNewObjData->objData.Copy(pOldObjData->objData);
54 Add(pNewObjData);
Lei Zhangd77f03f2015-12-28 13:12:26 -080055 } break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070056 case JS_GLOBALDATA_TYPE_NULL: {
57 CJS_KeyValue* pNewObjData = new CJS_KeyValue;
58 pNewObjData->sKey = pOldObjData->sKey;
59 pNewObjData->nType = pOldObjData->nType;
60 Add(pNewObjData);
Lei Zhangd77f03f2015-12-28 13:12:26 -080061 } break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070062 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -070063 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070064}
65
Nico Weber9d8ec5a2015-08-04 13:00:21 -070066void CJS_GlobalVariableArray::Add(CJS_KeyValue* p) {
67 array.Add(p);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070068}
69
Nico Weber9d8ec5a2015-08-04 13:00:21 -070070int CJS_GlobalVariableArray::Count() const {
71 return array.GetSize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070072}
73
Nico Weber9d8ec5a2015-08-04 13:00:21 -070074CJS_KeyValue* CJS_GlobalVariableArray::GetAt(int index) const {
75 return array.GetAt(index);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070076}
77
Nico Weber9d8ec5a2015-08-04 13:00:21 -070078void CJS_GlobalVariableArray::Empty() {
79 for (int i = 0, sz = array.GetSize(); i < sz; i++)
80 delete array.GetAt(i);
81 array.RemoveAll();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070082}
83
84/* -------------------------- CJS_GlobalData -------------------------- */
85
Nico Weber9d8ec5a2015-08-04 13:00:21 -070086#define READER_JS_GLOBALDATA_FILENAME L"Reader_JsGlobal.Data"
87#define PHANTOM_JS_GLOBALDATA_FILENAME L"Phantom_JsGlobal.Data"
88#define SDK_JS_GLOBALDATA_FILENAME L"SDK_JsGlobal.Data"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070089
Nico Weber9d8ec5a2015-08-04 13:00:21 -070090static const uint8_t JS_RC4KEY[] = {
91 0x19, 0xa8, 0xe8, 0x01, 0xf6, 0xa8, 0xb6, 0x4d, 0x82, 0x04, 0x45, 0x6d,
92 0xb4, 0xcf, 0xd7, 0x77, 0x67, 0xf9, 0x75, 0x9f, 0xf0, 0xe0, 0x1e, 0x51,
93 0xee, 0x46, 0xfd, 0x0b, 0xc9, 0x93, 0x25, 0x55, 0x4a, 0xee, 0xe0, 0x16,
94 0xd0, 0xdf, 0x8c, 0xfa, 0x2a, 0xa9, 0x49, 0xfd, 0x97, 0x1c, 0x0e, 0x22,
95 0x13, 0x28, 0x7c, 0xaf, 0xc4, 0xfc, 0x9c, 0x12, 0x65, 0x8c, 0x4e, 0x5b,
96 0x04, 0x75, 0x89, 0xc9, 0xb1, 0xed, 0x50, 0xca, 0x96, 0x6f, 0x1a, 0x7a,
97 0xfe, 0x58, 0x5d, 0xec, 0x19, 0x4a, 0xf6, 0x35, 0x6a, 0x97, 0x14, 0x00,
98 0x0e, 0xd0, 0x6b, 0xbb, 0xd5, 0x75, 0x55, 0x8b, 0x6e, 0x6b, 0x19, 0xa0,
99 0xf8, 0x77, 0xd5, 0xa3};
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700100
tsepez41a53ad2016-03-28 16:59:30 -0700101// Returns true if non-empty, setting sPropName
102static bool TrimPropName(const char* propname, CFX_ByteString* sPropName) {
103 ASSERT(propname);
104 *sPropName = propname;
105 sPropName->TrimLeft();
106 sPropName->TrimRight();
107 return sPropName->GetLength() != 0;
108}
109
Tom Sepezf4583622015-09-14 15:06:53 -0700110CJS_GlobalData* CJS_GlobalData::g_Instance = nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700111
Tom Sepezf4583622015-09-14 15:06:53 -0700112// static
113CJS_GlobalData* CJS_GlobalData::GetRetainedInstance(CPDFDoc_Environment* pApp) {
114 if (!g_Instance) {
Tom Sepezdfbf8e72015-10-14 14:17:26 -0700115 g_Instance = new CJS_GlobalData();
Tom Sepezf4583622015-09-14 15:06:53 -0700116 }
117 ++g_Instance->m_RefCount;
118 return g_Instance;
119}
120
121void CJS_GlobalData::Release() {
122 if (!--m_RefCount) {
123 delete g_Instance;
124 g_Instance = nullptr;
125 }
126}
127
tsepez41a53ad2016-03-28 16:59:30 -0700128CJS_GlobalData::CJS_GlobalData()
129 : m_RefCount(0), m_sFilePath(SDK_JS_GLOBALDATA_FILENAME) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700130 LoadGlobalPersistentVariables();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700131}
132
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700133CJS_GlobalData::~CJS_GlobalData() {
134 SaveGlobalPersisitentVariables();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700135}
136
tsepez41a53ad2016-03-28 16:59:30 -0700137CJS_GlobalData::iterator CJS_GlobalData::FindGlobalVariable(
138 const FX_CHAR* propname) {
139 for (auto it = m_arrayGlobalData.begin(); it != m_arrayGlobalData.end();
140 ++it) {
141 if ((*it)->data.sKey == propname)
142 return it;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700143 }
tsepez41a53ad2016-03-28 16:59:30 -0700144 return m_arrayGlobalData.end();
145}
146
147CJS_GlobalData::const_iterator CJS_GlobalData::FindGlobalVariable(
148 const FX_CHAR* propname) const {
149 for (auto it = m_arrayGlobalData.begin(); it != m_arrayGlobalData.end();
150 ++it) {
151 if ((*it)->data.sKey == propname)
152 return it;
153 }
154 return m_arrayGlobalData.end();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700155}
156
157CJS_GlobalData_Element* CJS_GlobalData::GetGlobalVariable(
158 const FX_CHAR* propname) {
tsepez41a53ad2016-03-28 16:59:30 -0700159 auto iter = FindGlobalVariable(propname);
160 return iter != m_arrayGlobalData.end() ? iter->get() : nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700161}
162
163void CJS_GlobalData::SetGlobalVariableNumber(const FX_CHAR* propname,
164 double dData) {
tsepez41a53ad2016-03-28 16:59:30 -0700165 CFX_ByteString sPropName;
166 if (!TrimPropName(propname, &sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700167 return;
168
169 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
170 pData->data.nType = JS_GLOBALDATA_TYPE_NUMBER;
171 pData->data.dData = dData;
tsepez41a53ad2016-03-28 16:59:30 -0700172 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700173 }
tsepez41a53ad2016-03-28 16:59:30 -0700174 std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
175 pNewData->data.sKey = sPropName;
176 pNewData->data.nType = JS_GLOBALDATA_TYPE_NUMBER;
177 pNewData->data.dData = dData;
178 m_arrayGlobalData.push_back(std::move(pNewData));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700179}
180
181void CJS_GlobalData::SetGlobalVariableBoolean(const FX_CHAR* propname,
182 bool bData) {
tsepez41a53ad2016-03-28 16:59:30 -0700183 CFX_ByteString sPropName;
184 if (!TrimPropName(propname, &sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700185 return;
186
187 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
188 pData->data.nType = JS_GLOBALDATA_TYPE_BOOLEAN;
189 pData->data.bData = bData;
tsepez41a53ad2016-03-28 16:59:30 -0700190 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700191 }
tsepez41a53ad2016-03-28 16:59:30 -0700192 std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
193 pNewData->data.sKey = sPropName;
194 pNewData->data.nType = JS_GLOBALDATA_TYPE_BOOLEAN;
195 pNewData->data.bData = bData;
196 m_arrayGlobalData.push_back(std::move(pNewData));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700197}
198
199void CJS_GlobalData::SetGlobalVariableString(const FX_CHAR* propname,
200 const CFX_ByteString& sData) {
tsepez41a53ad2016-03-28 16:59:30 -0700201 CFX_ByteString sPropName;
202 if (!TrimPropName(propname, &sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700203 return;
204
205 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
206 pData->data.nType = JS_GLOBALDATA_TYPE_STRING;
207 pData->data.sData = sData;
tsepez41a53ad2016-03-28 16:59:30 -0700208 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700209 }
tsepez41a53ad2016-03-28 16:59:30 -0700210 std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
211 pNewData->data.sKey = sPropName;
212 pNewData->data.nType = JS_GLOBALDATA_TYPE_STRING;
213 pNewData->data.sData = sData;
214 m_arrayGlobalData.push_back(std::move(pNewData));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700215}
216
217void CJS_GlobalData::SetGlobalVariableObject(
218 const FX_CHAR* propname,
219 const CJS_GlobalVariableArray& array) {
tsepez41a53ad2016-03-28 16:59:30 -0700220 CFX_ByteString sPropName;
221 if (!TrimPropName(propname, &sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700222 return;
223
224 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
225 pData->data.nType = JS_GLOBALDATA_TYPE_OBJECT;
226 pData->data.objData.Copy(array);
tsepez41a53ad2016-03-28 16:59:30 -0700227 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700228 }
tsepez41a53ad2016-03-28 16:59:30 -0700229 std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
230 pNewData->data.sKey = sPropName;
231 pNewData->data.nType = JS_GLOBALDATA_TYPE_OBJECT;
232 pNewData->data.objData.Copy(array);
233 m_arrayGlobalData.push_back(std::move(pNewData));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700234}
235
236void CJS_GlobalData::SetGlobalVariableNull(const FX_CHAR* propname) {
tsepez41a53ad2016-03-28 16:59:30 -0700237 CFX_ByteString sPropName;
238 if (!TrimPropName(propname, &sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700239 return;
240
241 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
242 pData->data.nType = JS_GLOBALDATA_TYPE_NULL;
tsepez41a53ad2016-03-28 16:59:30 -0700243 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700244 }
tsepez41a53ad2016-03-28 16:59:30 -0700245 std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
246 pNewData->data.sKey = sPropName;
247 pNewData->data.nType = JS_GLOBALDATA_TYPE_NULL;
248 m_arrayGlobalData.push_back(std::move(pNewData));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700249}
250
251FX_BOOL CJS_GlobalData::SetGlobalVariablePersistent(const FX_CHAR* propname,
252 FX_BOOL bPersistent) {
tsepez41a53ad2016-03-28 16:59:30 -0700253 CFX_ByteString sPropName;
254 if (!TrimPropName(propname, &sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700255 return FALSE;
256
tsepez41a53ad2016-03-28 16:59:30 -0700257 CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName);
258 if (!pData)
259 return FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700260
tsepez41a53ad2016-03-28 16:59:30 -0700261 pData->bPersistent = bPersistent;
262 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700263}
264
265FX_BOOL CJS_GlobalData::DeleteGlobalVariable(const FX_CHAR* propname) {
tsepez41a53ad2016-03-28 16:59:30 -0700266 CFX_ByteString sPropName;
267 if (!TrimPropName(propname, &sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700268 return FALSE;
269
tsepez41a53ad2016-03-28 16:59:30 -0700270 auto iter = FindGlobalVariable(sPropName);
271 if (iter == m_arrayGlobalData.end())
272 return FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700273
tsepez41a53ad2016-03-28 16:59:30 -0700274 m_arrayGlobalData.erase(iter);
275 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700276}
277
278int32_t CJS_GlobalData::GetSize() const {
tsepez41a53ad2016-03-28 16:59:30 -0700279 return pdfium::CollectionSize<int32_t>(m_arrayGlobalData);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700280}
281
282CJS_GlobalData_Element* CJS_GlobalData::GetAt(int index) const {
tsepez41a53ad2016-03-28 16:59:30 -0700283 if (index < 0 || index >= GetSize())
284 return nullptr;
285 return m_arrayGlobalData[index].get();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700286}
287
288void CJS_GlobalData::LoadGlobalPersistentVariables() {
289 uint8_t* pBuffer = NULL;
290 int32_t nLength = 0;
291
292 LoadFileBuffer(m_sFilePath.c_str(), pBuffer, nLength);
293 CRYPT_ArcFourCryptBlock(pBuffer, nLength, JS_RC4KEY, sizeof(JS_RC4KEY));
294
295 if (pBuffer) {
296 uint8_t* p = pBuffer;
Tom Sepez62a70f92016-03-21 15:00:20 -0700297 uint16_t wType = *((uint16_t*)p);
298 p += sizeof(uint16_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700299
Tom Sepez62a70f92016-03-21 15:00:20 -0700300 // uint16_t wTemp = (uint16_t)(('X' << 8) | 'F');
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700301
Tom Sepez62a70f92016-03-21 15:00:20 -0700302 if (wType == (uint16_t)(('X' << 8) | 'F')) {
303 uint16_t wVersion = *((uint16_t*)p);
304 p += sizeof(uint16_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700305
306 ASSERT(wVersion <= 2);
307
tsepezc3255f52016-03-25 14:52:27 -0700308 uint32_t dwCount = *((uint32_t*)p);
309 p += sizeof(uint32_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700310
tsepezc3255f52016-03-25 14:52:27 -0700311 uint32_t dwSize = *((uint32_t*)p);
312 p += sizeof(uint32_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700313
tsepezc3255f52016-03-25 14:52:27 -0700314 if (dwSize == nLength - sizeof(uint16_t) * 2 - sizeof(uint32_t) * 2) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700315 for (int32_t i = 0, sz = dwCount; i < sz; i++) {
316 if (p > pBuffer + nLength)
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700317 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700318
tsepezc3255f52016-03-25 14:52:27 -0700319 uint32_t dwNameLen = *((uint32_t*)p);
320 p += sizeof(uint32_t);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700321
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700322 if (p + dwNameLen > pBuffer + nLength)
323 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700324
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700325 CFX_ByteString sEntry = CFX_ByteString(p, dwNameLen);
326 p += sizeof(char) * dwNameLen;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700327
Tom Sepez62a70f92016-03-21 15:00:20 -0700328 uint16_t wDataType = *((uint16_t*)p);
329 p += sizeof(uint16_t);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700330
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700331 switch (wDataType) {
332 case JS_GLOBALDATA_TYPE_NUMBER: {
333 double dData = 0;
334 switch (wVersion) {
335 case 1: {
tsepezc3255f52016-03-25 14:52:27 -0700336 uint32_t dwData = *((uint32_t*)p);
337 p += sizeof(uint32_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700338 dData = dwData;
339 } break;
340 case 2: {
341 dData = *((double*)p);
342 p += sizeof(double);
343 } break;
344 }
345 SetGlobalVariableNumber(sEntry, dData);
346 SetGlobalVariablePersistent(sEntry, TRUE);
347 } break;
348 case JS_GLOBALDATA_TYPE_BOOLEAN: {
Tom Sepez62a70f92016-03-21 15:00:20 -0700349 uint16_t wData = *((uint16_t*)p);
350 p += sizeof(uint16_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700351 SetGlobalVariableBoolean(sEntry, (bool)(wData == 1));
352 SetGlobalVariablePersistent(sEntry, TRUE);
353 } break;
354 case JS_GLOBALDATA_TYPE_STRING: {
tsepezc3255f52016-03-25 14:52:27 -0700355 uint32_t dwLength = *((uint32_t*)p);
356 p += sizeof(uint32_t);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700357
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700358 if (p + dwLength > pBuffer + nLength)
359 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700360
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700361 SetGlobalVariableString(sEntry, CFX_ByteString(p, dwLength));
362 SetGlobalVariablePersistent(sEntry, TRUE);
363 p += sizeof(char) * dwLength;
364 } break;
365 case JS_GLOBALDATA_TYPE_NULL: {
366 SetGlobalVariableNull(sEntry);
367 SetGlobalVariablePersistent(sEntry, TRUE);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700368 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700369 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700370 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700371 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700372 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700373 FX_Free(pBuffer);
374 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700375}
376
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700377void CJS_GlobalData::SaveGlobalPersisitentVariables() {
tsepezc3255f52016-03-25 14:52:27 -0700378 uint32_t nCount = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700379 CFX_BinaryBuf sData;
tsepez41a53ad2016-03-28 16:59:30 -0700380 for (const auto& pElement : m_arrayGlobalData) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700381 if (pElement->bPersistent) {
382 CFX_BinaryBuf sElement;
383 MakeByteString(pElement->data.sKey, &pElement->data, sElement);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700384 if (sData.GetSize() + sElement.GetSize() > JS_MAXGLOBALDATA)
385 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700386
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700387 sData.AppendBlock(sElement.GetBuffer(), sElement.GetSize());
388 nCount++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700389 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700390 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700391
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700392 CFX_BinaryBuf sFile;
Tom Sepez62a70f92016-03-21 15:00:20 -0700393 uint16_t wType = (uint16_t)(('X' << 8) | 'F');
394 sFile.AppendBlock(&wType, sizeof(uint16_t));
395 uint16_t wVersion = 2;
396 sFile.AppendBlock(&wVersion, sizeof(uint16_t));
tsepezc3255f52016-03-25 14:52:27 -0700397 sFile.AppendBlock(&nCount, sizeof(uint32_t));
398 uint32_t dwSize = sData.GetSize();
399 sFile.AppendBlock(&dwSize, sizeof(uint32_t));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700400
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700401 sFile.AppendBlock(sData.GetBuffer(), sData.GetSize());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700402
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700403 CRYPT_ArcFourCryptBlock(sFile.GetBuffer(), sFile.GetSize(), JS_RC4KEY,
404 sizeof(JS_RC4KEY));
405 WriteFileBuffer(m_sFilePath.c_str(), (const FX_CHAR*)sFile.GetBuffer(),
406 sFile.GetSize());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700407}
408
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700409void CJS_GlobalData::LoadFileBuffer(const FX_WCHAR* sFilePath,
410 uint8_t*& pBuffer,
411 int32_t& nLength) {
412 // UnSupport.
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700413}
414
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700415void CJS_GlobalData::WriteFileBuffer(const FX_WCHAR* sFilePath,
416 const FX_CHAR* pBuffer,
417 int32_t nLength) {
418 // UnSupport.
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700419}
420
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700421void CJS_GlobalData::MakeByteString(const CFX_ByteString& name,
422 CJS_KeyValue* pData,
423 CFX_BinaryBuf& sData) {
Tom Sepez62a70f92016-03-21 15:00:20 -0700424 uint16_t wType = (uint16_t)pData->nType;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700425 switch (wType) {
426 case JS_GLOBALDATA_TYPE_NUMBER: {
tsepezc3255f52016-03-25 14:52:27 -0700427 uint32_t dwNameLen = (uint32_t)name.GetLength();
428 sData.AppendBlock(&dwNameLen, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700429 sData.AppendString(name);
Tom Sepez62a70f92016-03-21 15:00:20 -0700430 sData.AppendBlock(&wType, sizeof(uint16_t));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700431
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700432 double dData = pData->dData;
433 sData.AppendBlock(&dData, sizeof(double));
434 } break;
435 case JS_GLOBALDATA_TYPE_BOOLEAN: {
tsepezc3255f52016-03-25 14:52:27 -0700436 uint32_t dwNameLen = (uint32_t)name.GetLength();
437 sData.AppendBlock(&dwNameLen, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700438 sData.AppendString(name);
Tom Sepez62a70f92016-03-21 15:00:20 -0700439 sData.AppendBlock(&wType, sizeof(uint16_t));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700440
Tom Sepez62a70f92016-03-21 15:00:20 -0700441 uint16_t wData = (uint16_t)pData->bData;
442 sData.AppendBlock(&wData, sizeof(uint16_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700443 } break;
444 case JS_GLOBALDATA_TYPE_STRING: {
tsepezc3255f52016-03-25 14:52:27 -0700445 uint32_t dwNameLen = (uint32_t)name.GetLength();
446 sData.AppendBlock(&dwNameLen, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700447 sData.AppendString(name);
Tom Sepez62a70f92016-03-21 15:00:20 -0700448 sData.AppendBlock(&wType, sizeof(uint16_t));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700449
tsepezc3255f52016-03-25 14:52:27 -0700450 uint32_t dwDataLen = (uint32_t)pData->sData.GetLength();
451 sData.AppendBlock(&dwDataLen, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700452 sData.AppendString(pData->sData);
453 } break;
454 case JS_GLOBALDATA_TYPE_NULL: {
tsepezc3255f52016-03-25 14:52:27 -0700455 uint32_t dwNameLen = (uint32_t)name.GetLength();
456 sData.AppendBlock(&dwNameLen, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700457 sData.AppendString(name);
tsepezc3255f52016-03-25 14:52:27 -0700458 sData.AppendBlock(&wType, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700459 } break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700460 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700461 break;
462 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700463}