blob: aaa25ff4748310c964ad6a6fa891acd4228c6223 [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) {
weili98963392016-06-07 11:28:31 -070064 m_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 {
weili98963392016-06-07 11:28:31 -070068 return m_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 {
weili98963392016-06-07 11:28:31 -070072 return m_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() {
weili98963392016-06-07 11:28:31 -070076 for (int i = 0, sz = m_Array.GetSize(); i < sz; i++)
77 delete m_Array.GetAt(i);
78 m_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
tsepez24a48882016-04-11 15:18:40 -070097static bool TrimPropName(CFX_ByteString* sPropName) {
tsepez41a53ad2016-03-28 16:59:30 -070098 sPropName->TrimLeft();
99 sPropName->TrimRight();
100 return sPropName->GetLength() != 0;
101}
102
Tom Sepezf4583622015-09-14 15:06:53 -0700103CJS_GlobalData* CJS_GlobalData::g_Instance = nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700104
Tom Sepezf4583622015-09-14 15:06:53 -0700105// static
106CJS_GlobalData* CJS_GlobalData::GetRetainedInstance(CPDFDoc_Environment* pApp) {
107 if (!g_Instance) {
Tom Sepezdfbf8e72015-10-14 14:17:26 -0700108 g_Instance = new CJS_GlobalData();
Tom Sepezf4583622015-09-14 15:06:53 -0700109 }
110 ++g_Instance->m_RefCount;
111 return g_Instance;
112}
113
114void CJS_GlobalData::Release() {
115 if (!--m_RefCount) {
116 delete g_Instance;
117 g_Instance = nullptr;
118 }
119}
120
tsepez41a53ad2016-03-28 16:59:30 -0700121CJS_GlobalData::CJS_GlobalData()
122 : m_RefCount(0), m_sFilePath(SDK_JS_GLOBALDATA_FILENAME) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700123 LoadGlobalPersistentVariables();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700124}
125
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700126CJS_GlobalData::~CJS_GlobalData() {
127 SaveGlobalPersisitentVariables();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700128}
129
tsepez41a53ad2016-03-28 16:59:30 -0700130CJS_GlobalData::iterator CJS_GlobalData::FindGlobalVariable(
tsepez24a48882016-04-11 15:18:40 -0700131 const CFX_ByteString& propname) {
tsepez41a53ad2016-03-28 16:59:30 -0700132 for (auto it = m_arrayGlobalData.begin(); it != m_arrayGlobalData.end();
133 ++it) {
134 if ((*it)->data.sKey == propname)
135 return it;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700136 }
tsepez41a53ad2016-03-28 16:59:30 -0700137 return m_arrayGlobalData.end();
138}
139
140CJS_GlobalData::const_iterator CJS_GlobalData::FindGlobalVariable(
tsepez24a48882016-04-11 15:18:40 -0700141 const CFX_ByteString& propname) const {
tsepez41a53ad2016-03-28 16:59:30 -0700142 for (auto it = m_arrayGlobalData.begin(); it != m_arrayGlobalData.end();
143 ++it) {
144 if ((*it)->data.sKey == propname)
145 return it;
146 }
147 return m_arrayGlobalData.end();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700148}
149
150CJS_GlobalData_Element* CJS_GlobalData::GetGlobalVariable(
tsepez24a48882016-04-11 15:18:40 -0700151 const CFX_ByteString& propname) {
tsepez41a53ad2016-03-28 16:59:30 -0700152 auto iter = FindGlobalVariable(propname);
153 return iter != m_arrayGlobalData.end() ? iter->get() : nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700154}
155
tsepez24a48882016-04-11 15:18:40 -0700156void CJS_GlobalData::SetGlobalVariableNumber(const CFX_ByteString& propname,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700157 double dData) {
tsepez24a48882016-04-11 15:18:40 -0700158 CFX_ByteString sPropName(propname);
159 if (!TrimPropName(&sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700160 return;
161
162 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
163 pData->data.nType = JS_GLOBALDATA_TYPE_NUMBER;
164 pData->data.dData = dData;
tsepez41a53ad2016-03-28 16:59:30 -0700165 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700166 }
tsepez41a53ad2016-03-28 16:59:30 -0700167 std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
168 pNewData->data.sKey = sPropName;
169 pNewData->data.nType = JS_GLOBALDATA_TYPE_NUMBER;
170 pNewData->data.dData = dData;
171 m_arrayGlobalData.push_back(std::move(pNewData));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700172}
173
tsepez24a48882016-04-11 15:18:40 -0700174void CJS_GlobalData::SetGlobalVariableBoolean(const CFX_ByteString& propname,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700175 bool bData) {
tsepez24a48882016-04-11 15:18:40 -0700176 CFX_ByteString sPropName(propname);
177 if (!TrimPropName(&sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700178 return;
179
180 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
181 pData->data.nType = JS_GLOBALDATA_TYPE_BOOLEAN;
182 pData->data.bData = bData;
tsepez41a53ad2016-03-28 16:59:30 -0700183 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700184 }
tsepez41a53ad2016-03-28 16:59:30 -0700185 std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
186 pNewData->data.sKey = sPropName;
187 pNewData->data.nType = JS_GLOBALDATA_TYPE_BOOLEAN;
188 pNewData->data.bData = bData;
189 m_arrayGlobalData.push_back(std::move(pNewData));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700190}
191
tsepez24a48882016-04-11 15:18:40 -0700192void CJS_GlobalData::SetGlobalVariableString(const CFX_ByteString& propname,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700193 const CFX_ByteString& sData) {
tsepez24a48882016-04-11 15:18:40 -0700194 CFX_ByteString sPropName(propname);
195 if (!TrimPropName(&sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700196 return;
197
198 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
199 pData->data.nType = JS_GLOBALDATA_TYPE_STRING;
200 pData->data.sData = sData;
tsepez41a53ad2016-03-28 16:59:30 -0700201 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700202 }
tsepez41a53ad2016-03-28 16:59:30 -0700203 std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
204 pNewData->data.sKey = sPropName;
205 pNewData->data.nType = JS_GLOBALDATA_TYPE_STRING;
206 pNewData->data.sData = sData;
207 m_arrayGlobalData.push_back(std::move(pNewData));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700208}
209
210void CJS_GlobalData::SetGlobalVariableObject(
tsepez24a48882016-04-11 15:18:40 -0700211 const CFX_ByteString& propname,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700212 const CJS_GlobalVariableArray& array) {
tsepez24a48882016-04-11 15:18:40 -0700213 CFX_ByteString sPropName(propname);
214 if (!TrimPropName(&sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700215 return;
216
217 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
218 pData->data.nType = JS_GLOBALDATA_TYPE_OBJECT;
219 pData->data.objData.Copy(array);
tsepez41a53ad2016-03-28 16:59:30 -0700220 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700221 }
tsepez41a53ad2016-03-28 16:59:30 -0700222 std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
223 pNewData->data.sKey = sPropName;
224 pNewData->data.nType = JS_GLOBALDATA_TYPE_OBJECT;
225 pNewData->data.objData.Copy(array);
226 m_arrayGlobalData.push_back(std::move(pNewData));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700227}
228
tsepez24a48882016-04-11 15:18:40 -0700229void CJS_GlobalData::SetGlobalVariableNull(const CFX_ByteString& propname) {
230 CFX_ByteString sPropName(propname);
231 if (!TrimPropName(&sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700232 return;
233
234 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
235 pData->data.nType = JS_GLOBALDATA_TYPE_NULL;
tsepez41a53ad2016-03-28 16:59:30 -0700236 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700237 }
tsepez41a53ad2016-03-28 16:59:30 -0700238 std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
239 pNewData->data.sKey = sPropName;
240 pNewData->data.nType = JS_GLOBALDATA_TYPE_NULL;
241 m_arrayGlobalData.push_back(std::move(pNewData));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700242}
243
tsepez24a48882016-04-11 15:18:40 -0700244FX_BOOL CJS_GlobalData::SetGlobalVariablePersistent(
245 const CFX_ByteString& propname,
246 FX_BOOL bPersistent) {
247 CFX_ByteString sPropName(propname);
248 if (!TrimPropName(&sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700249 return FALSE;
250
tsepez41a53ad2016-03-28 16:59:30 -0700251 CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName);
252 if (!pData)
253 return FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700254
tsepez41a53ad2016-03-28 16:59:30 -0700255 pData->bPersistent = bPersistent;
256 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700257}
258
tsepez24a48882016-04-11 15:18:40 -0700259FX_BOOL CJS_GlobalData::DeleteGlobalVariable(const CFX_ByteString& propname) {
260 CFX_ByteString sPropName(propname);
261 if (!TrimPropName(&sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700262 return FALSE;
263
tsepez41a53ad2016-03-28 16:59:30 -0700264 auto iter = FindGlobalVariable(sPropName);
265 if (iter == m_arrayGlobalData.end())
266 return FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700267
tsepez41a53ad2016-03-28 16:59:30 -0700268 m_arrayGlobalData.erase(iter);
269 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700270}
271
272int32_t CJS_GlobalData::GetSize() const {
tsepez41a53ad2016-03-28 16:59:30 -0700273 return pdfium::CollectionSize<int32_t>(m_arrayGlobalData);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700274}
275
276CJS_GlobalData_Element* CJS_GlobalData::GetAt(int index) const {
tsepez41a53ad2016-03-28 16:59:30 -0700277 if (index < 0 || index >= GetSize())
278 return nullptr;
279 return m_arrayGlobalData[index].get();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700280}
281
282void CJS_GlobalData::LoadGlobalPersistentVariables() {
thestig1cd352e2016-06-07 17:53:06 -0700283 uint8_t* pBuffer = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700284 int32_t nLength = 0;
285
286 LoadFileBuffer(m_sFilePath.c_str(), pBuffer, nLength);
287 CRYPT_ArcFourCryptBlock(pBuffer, nLength, JS_RC4KEY, sizeof(JS_RC4KEY));
288
289 if (pBuffer) {
290 uint8_t* p = pBuffer;
Tom Sepez62a70f92016-03-21 15:00:20 -0700291 uint16_t wType = *((uint16_t*)p);
292 p += sizeof(uint16_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700293
Tom Sepez62a70f92016-03-21 15:00:20 -0700294 if (wType == (uint16_t)(('X' << 8) | 'F')) {
295 uint16_t wVersion = *((uint16_t*)p);
296 p += sizeof(uint16_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700297
298 ASSERT(wVersion <= 2);
299
tsepezc3255f52016-03-25 14:52:27 -0700300 uint32_t dwCount = *((uint32_t*)p);
301 p += sizeof(uint32_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700302
tsepezc3255f52016-03-25 14:52:27 -0700303 uint32_t dwSize = *((uint32_t*)p);
304 p += sizeof(uint32_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700305
tsepezc3255f52016-03-25 14:52:27 -0700306 if (dwSize == nLength - sizeof(uint16_t) * 2 - sizeof(uint32_t) * 2) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700307 for (int32_t i = 0, sz = dwCount; i < sz; i++) {
308 if (p > pBuffer + nLength)
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700309 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700310
tsepezc3255f52016-03-25 14:52:27 -0700311 uint32_t dwNameLen = *((uint32_t*)p);
312 p += sizeof(uint32_t);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700313
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700314 if (p + dwNameLen > pBuffer + nLength)
315 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700316
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700317 CFX_ByteString sEntry = CFX_ByteString(p, dwNameLen);
318 p += sizeof(char) * dwNameLen;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700319
Tom Sepez62a70f92016-03-21 15:00:20 -0700320 uint16_t wDataType = *((uint16_t*)p);
321 p += sizeof(uint16_t);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700322
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700323 switch (wDataType) {
324 case JS_GLOBALDATA_TYPE_NUMBER: {
325 double dData = 0;
326 switch (wVersion) {
327 case 1: {
tsepezc3255f52016-03-25 14:52:27 -0700328 uint32_t dwData = *((uint32_t*)p);
329 p += sizeof(uint32_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700330 dData = dwData;
331 } break;
332 case 2: {
333 dData = *((double*)p);
334 p += sizeof(double);
335 } break;
336 }
337 SetGlobalVariableNumber(sEntry, dData);
338 SetGlobalVariablePersistent(sEntry, TRUE);
339 } break;
340 case JS_GLOBALDATA_TYPE_BOOLEAN: {
Tom Sepez62a70f92016-03-21 15:00:20 -0700341 uint16_t wData = *((uint16_t*)p);
342 p += sizeof(uint16_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700343 SetGlobalVariableBoolean(sEntry, (bool)(wData == 1));
344 SetGlobalVariablePersistent(sEntry, TRUE);
345 } break;
346 case JS_GLOBALDATA_TYPE_STRING: {
tsepezc3255f52016-03-25 14:52:27 -0700347 uint32_t dwLength = *((uint32_t*)p);
348 p += sizeof(uint32_t);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700349
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700350 if (p + dwLength > pBuffer + nLength)
351 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700352
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700353 SetGlobalVariableString(sEntry, CFX_ByteString(p, dwLength));
354 SetGlobalVariablePersistent(sEntry, TRUE);
355 p += sizeof(char) * dwLength;
356 } break;
357 case JS_GLOBALDATA_TYPE_NULL: {
358 SetGlobalVariableNull(sEntry);
359 SetGlobalVariablePersistent(sEntry, TRUE);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700360 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700361 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700362 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700363 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700364 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700365 FX_Free(pBuffer);
366 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700367}
368
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700369void CJS_GlobalData::SaveGlobalPersisitentVariables() {
tsepezc3255f52016-03-25 14:52:27 -0700370 uint32_t nCount = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700371 CFX_BinaryBuf sData;
tsepez41a53ad2016-03-28 16:59:30 -0700372 for (const auto& pElement : m_arrayGlobalData) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700373 if (pElement->bPersistent) {
374 CFX_BinaryBuf sElement;
375 MakeByteString(pElement->data.sKey, &pElement->data, sElement);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700376 if (sData.GetSize() + sElement.GetSize() > JS_MAXGLOBALDATA)
377 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700378
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700379 sData.AppendBlock(sElement.GetBuffer(), sElement.GetSize());
380 nCount++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700381 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700382 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700383
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700384 CFX_BinaryBuf sFile;
Tom Sepez62a70f92016-03-21 15:00:20 -0700385 uint16_t wType = (uint16_t)(('X' << 8) | 'F');
386 sFile.AppendBlock(&wType, sizeof(uint16_t));
387 uint16_t wVersion = 2;
388 sFile.AppendBlock(&wVersion, sizeof(uint16_t));
tsepezc3255f52016-03-25 14:52:27 -0700389 sFile.AppendBlock(&nCount, sizeof(uint32_t));
390 uint32_t dwSize = sData.GetSize();
391 sFile.AppendBlock(&dwSize, sizeof(uint32_t));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700392
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700393 sFile.AppendBlock(sData.GetBuffer(), sData.GetSize());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700394
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700395 CRYPT_ArcFourCryptBlock(sFile.GetBuffer(), sFile.GetSize(), JS_RC4KEY,
396 sizeof(JS_RC4KEY));
397 WriteFileBuffer(m_sFilePath.c_str(), (const FX_CHAR*)sFile.GetBuffer(),
398 sFile.GetSize());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700399}
400
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700401void CJS_GlobalData::LoadFileBuffer(const FX_WCHAR* sFilePath,
402 uint8_t*& pBuffer,
403 int32_t& nLength) {
404 // UnSupport.
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700405}
406
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700407void CJS_GlobalData::WriteFileBuffer(const FX_WCHAR* sFilePath,
408 const FX_CHAR* pBuffer,
409 int32_t nLength) {
410 // UnSupport.
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700411}
412
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700413void CJS_GlobalData::MakeByteString(const CFX_ByteString& name,
414 CJS_KeyValue* pData,
415 CFX_BinaryBuf& sData) {
Tom Sepez62a70f92016-03-21 15:00:20 -0700416 uint16_t wType = (uint16_t)pData->nType;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700417 switch (wType) {
418 case JS_GLOBALDATA_TYPE_NUMBER: {
tsepezc3255f52016-03-25 14:52:27 -0700419 uint32_t dwNameLen = (uint32_t)name.GetLength();
420 sData.AppendBlock(&dwNameLen, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700421 sData.AppendString(name);
Tom Sepez62a70f92016-03-21 15:00:20 -0700422 sData.AppendBlock(&wType, sizeof(uint16_t));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700423
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700424 double dData = pData->dData;
425 sData.AppendBlock(&dData, sizeof(double));
426 } break;
427 case JS_GLOBALDATA_TYPE_BOOLEAN: {
tsepezc3255f52016-03-25 14:52:27 -0700428 uint32_t dwNameLen = (uint32_t)name.GetLength();
429 sData.AppendBlock(&dwNameLen, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700430 sData.AppendString(name);
Tom Sepez62a70f92016-03-21 15:00:20 -0700431 sData.AppendBlock(&wType, sizeof(uint16_t));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700432
Tom Sepez62a70f92016-03-21 15:00:20 -0700433 uint16_t wData = (uint16_t)pData->bData;
434 sData.AppendBlock(&wData, sizeof(uint16_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700435 } break;
436 case JS_GLOBALDATA_TYPE_STRING: {
tsepezc3255f52016-03-25 14:52:27 -0700437 uint32_t dwNameLen = (uint32_t)name.GetLength();
438 sData.AppendBlock(&dwNameLen, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700439 sData.AppendString(name);
Tom Sepez62a70f92016-03-21 15:00:20 -0700440 sData.AppendBlock(&wType, sizeof(uint16_t));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700441
tsepezc3255f52016-03-25 14:52:27 -0700442 uint32_t dwDataLen = (uint32_t)pData->sData.GetLength();
443 sData.AppendBlock(&dwDataLen, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700444 sData.AppendString(pData->sData);
445 } break;
446 case JS_GLOBALDATA_TYPE_NULL: {
tsepezc3255f52016-03-25 14:52:27 -0700447 uint32_t dwNameLen = (uint32_t)name.GetLength();
448 sData.AppendBlock(&dwNameLen, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700449 sData.AppendString(name);
tsepezc3255f52016-03-25 14:52:27 -0700450 sData.AppendBlock(&wType, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700451 } break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700452 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700453 break;
454 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700455}