blob: 580cb466e6fa608eec7304eb3df5732ffd050aec [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
dsinclairb1469a22016-09-29 10:00:05 -07009#include "core/fdrm/crypto/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 -070014#define READER_JS_GLOBALDATA_FILENAME L"Reader_JsGlobal.Data"
15#define PHANTOM_JS_GLOBALDATA_FILENAME L"Phantom_JsGlobal.Data"
16#define SDK_JS_GLOBALDATA_FILENAME L"SDK_JsGlobal.Data"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070017
weili47228ac2016-07-20 10:35:31 -070018namespace {
19
20const uint8_t JS_RC4KEY[] = {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070021 0x19, 0xa8, 0xe8, 0x01, 0xf6, 0xa8, 0xb6, 0x4d, 0x82, 0x04, 0x45, 0x6d,
22 0xb4, 0xcf, 0xd7, 0x77, 0x67, 0xf9, 0x75, 0x9f, 0xf0, 0xe0, 0x1e, 0x51,
23 0xee, 0x46, 0xfd, 0x0b, 0xc9, 0x93, 0x25, 0x55, 0x4a, 0xee, 0xe0, 0x16,
24 0xd0, 0xdf, 0x8c, 0xfa, 0x2a, 0xa9, 0x49, 0xfd, 0x97, 0x1c, 0x0e, 0x22,
25 0x13, 0x28, 0x7c, 0xaf, 0xc4, 0xfc, 0x9c, 0x12, 0x65, 0x8c, 0x4e, 0x5b,
26 0x04, 0x75, 0x89, 0xc9, 0xb1, 0xed, 0x50, 0xca, 0x96, 0x6f, 0x1a, 0x7a,
27 0xfe, 0x58, 0x5d, 0xec, 0x19, 0x4a, 0xf6, 0x35, 0x6a, 0x97, 0x14, 0x00,
28 0x0e, 0xd0, 0x6b, 0xbb, 0xd5, 0x75, 0x55, 0x8b, 0x6e, 0x6b, 0x19, 0xa0,
29 0xf8, 0x77, 0xd5, 0xa3};
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070030
tsepez41a53ad2016-03-28 16:59:30 -070031// Returns true if non-empty, setting sPropName
weili47228ac2016-07-20 10:35:31 -070032bool TrimPropName(CFX_ByteString* sPropName) {
tsepez41a53ad2016-03-28 16:59:30 -070033 sPropName->TrimLeft();
34 sPropName->TrimRight();
35 return sPropName->GetLength() != 0;
36}
37
weili47228ac2016-07-20 10:35:31 -070038CJS_GlobalData* g_pInstance = nullptr;
39
40} // namespace
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070041
Tom Sepezf4583622015-09-14 15:06:53 -070042// static
dsinclair735606d2016-10-05 15:47:02 -070043CJS_GlobalData* CJS_GlobalData::GetRetainedInstance(
44 CPDFSDK_FormFillEnvironment* pApp) {
weili47228ac2016-07-20 10:35:31 -070045 if (!g_pInstance) {
46 g_pInstance = new CJS_GlobalData();
Tom Sepezf4583622015-09-14 15:06:53 -070047 }
weili47228ac2016-07-20 10:35:31 -070048 ++g_pInstance->m_RefCount;
49 return g_pInstance;
Tom Sepezf4583622015-09-14 15:06:53 -070050}
51
52void CJS_GlobalData::Release() {
53 if (!--m_RefCount) {
weili47228ac2016-07-20 10:35:31 -070054 delete g_pInstance;
55 g_pInstance = nullptr;
Tom Sepezf4583622015-09-14 15:06:53 -070056 }
57}
58
tsepez41a53ad2016-03-28 16:59:30 -070059CJS_GlobalData::CJS_GlobalData()
60 : m_RefCount(0), m_sFilePath(SDK_JS_GLOBALDATA_FILENAME) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070061 LoadGlobalPersistentVariables();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070062}
63
Nico Weber9d8ec5a2015-08-04 13:00:21 -070064CJS_GlobalData::~CJS_GlobalData() {
65 SaveGlobalPersisitentVariables();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070066}
67
tsepez41a53ad2016-03-28 16:59:30 -070068CJS_GlobalData::iterator CJS_GlobalData::FindGlobalVariable(
tsepez24a48882016-04-11 15:18:40 -070069 const CFX_ByteString& propname) {
tsepez41a53ad2016-03-28 16:59:30 -070070 for (auto it = m_arrayGlobalData.begin(); it != m_arrayGlobalData.end();
71 ++it) {
72 if ((*it)->data.sKey == propname)
73 return it;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070074 }
tsepez41a53ad2016-03-28 16:59:30 -070075 return m_arrayGlobalData.end();
76}
77
78CJS_GlobalData::const_iterator CJS_GlobalData::FindGlobalVariable(
tsepez24a48882016-04-11 15:18:40 -070079 const CFX_ByteString& propname) const {
tsepez41a53ad2016-03-28 16:59:30 -070080 for (auto it = m_arrayGlobalData.begin(); it != m_arrayGlobalData.end();
81 ++it) {
82 if ((*it)->data.sKey == propname)
83 return it;
84 }
85 return m_arrayGlobalData.end();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070086}
87
88CJS_GlobalData_Element* CJS_GlobalData::GetGlobalVariable(
tsepez24a48882016-04-11 15:18:40 -070089 const CFX_ByteString& propname) {
tsepez41a53ad2016-03-28 16:59:30 -070090 auto iter = FindGlobalVariable(propname);
91 return iter != m_arrayGlobalData.end() ? iter->get() : nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070092}
93
tsepez24a48882016-04-11 15:18:40 -070094void CJS_GlobalData::SetGlobalVariableNumber(const CFX_ByteString& propname,
Nico Weber9d8ec5a2015-08-04 13:00:21 -070095 double dData) {
tsepez24a48882016-04-11 15:18:40 -070096 CFX_ByteString sPropName(propname);
97 if (!TrimPropName(&sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -070098 return;
99
100 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
weili47228ac2016-07-20 10:35:31 -0700101 pData->data.nType = JS_GlobalDataType::NUMBER;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700102 pData->data.dData = dData;
tsepez41a53ad2016-03-28 16:59:30 -0700103 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700104 }
tsepez41a53ad2016-03-28 16:59:30 -0700105 std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
106 pNewData->data.sKey = sPropName;
weili47228ac2016-07-20 10:35:31 -0700107 pNewData->data.nType = JS_GlobalDataType::NUMBER;
tsepez41a53ad2016-03-28 16:59:30 -0700108 pNewData->data.dData = dData;
109 m_arrayGlobalData.push_back(std::move(pNewData));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700110}
111
tsepez24a48882016-04-11 15:18:40 -0700112void CJS_GlobalData::SetGlobalVariableBoolean(const CFX_ByteString& propname,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700113 bool bData) {
tsepez24a48882016-04-11 15:18:40 -0700114 CFX_ByteString sPropName(propname);
115 if (!TrimPropName(&sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700116 return;
117
118 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
weili47228ac2016-07-20 10:35:31 -0700119 pData->data.nType = JS_GlobalDataType::BOOLEAN;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700120 pData->data.bData = bData;
tsepez41a53ad2016-03-28 16:59:30 -0700121 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700122 }
tsepez41a53ad2016-03-28 16:59:30 -0700123 std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
124 pNewData->data.sKey = sPropName;
weili47228ac2016-07-20 10:35:31 -0700125 pNewData->data.nType = JS_GlobalDataType::BOOLEAN;
tsepez41a53ad2016-03-28 16:59:30 -0700126 pNewData->data.bData = bData;
127 m_arrayGlobalData.push_back(std::move(pNewData));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700128}
129
tsepez24a48882016-04-11 15:18:40 -0700130void CJS_GlobalData::SetGlobalVariableString(const CFX_ByteString& propname,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700131 const CFX_ByteString& sData) {
tsepez24a48882016-04-11 15:18:40 -0700132 CFX_ByteString sPropName(propname);
133 if (!TrimPropName(&sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700134 return;
135
136 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
weili47228ac2016-07-20 10:35:31 -0700137 pData->data.nType = JS_GlobalDataType::STRING;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700138 pData->data.sData = sData;
tsepez41a53ad2016-03-28 16:59:30 -0700139 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700140 }
tsepez41a53ad2016-03-28 16:59:30 -0700141 std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
142 pNewData->data.sKey = sPropName;
weili47228ac2016-07-20 10:35:31 -0700143 pNewData->data.nType = JS_GlobalDataType::STRING;
tsepez41a53ad2016-03-28 16:59:30 -0700144 pNewData->data.sData = sData;
145 m_arrayGlobalData.push_back(std::move(pNewData));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700146}
147
148void CJS_GlobalData::SetGlobalVariableObject(
tsepez24a48882016-04-11 15:18:40 -0700149 const CFX_ByteString& propname,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700150 const CJS_GlobalVariableArray& array) {
tsepez24a48882016-04-11 15:18:40 -0700151 CFX_ByteString sPropName(propname);
152 if (!TrimPropName(&sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700153 return;
154
155 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
weili47228ac2016-07-20 10:35:31 -0700156 pData->data.nType = JS_GlobalDataType::OBJECT;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700157 pData->data.objData.Copy(array);
tsepez41a53ad2016-03-28 16:59:30 -0700158 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700159 }
tsepez41a53ad2016-03-28 16:59:30 -0700160 std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
161 pNewData->data.sKey = sPropName;
weili47228ac2016-07-20 10:35:31 -0700162 pNewData->data.nType = JS_GlobalDataType::OBJECT;
tsepez41a53ad2016-03-28 16:59:30 -0700163 pNewData->data.objData.Copy(array);
164 m_arrayGlobalData.push_back(std::move(pNewData));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700165}
166
tsepez24a48882016-04-11 15:18:40 -0700167void CJS_GlobalData::SetGlobalVariableNull(const CFX_ByteString& propname) {
168 CFX_ByteString sPropName(propname);
169 if (!TrimPropName(&sPropName))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700170 return;
171
172 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
weili47228ac2016-07-20 10:35:31 -0700173 pData->data.nType = JS_GlobalDataType::NULLOBJ;
tsepez41a53ad2016-03-28 16:59:30 -0700174 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700175 }
tsepez41a53ad2016-03-28 16:59:30 -0700176 std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
177 pNewData->data.sKey = sPropName;
weili47228ac2016-07-20 10:35:31 -0700178 pNewData->data.nType = JS_GlobalDataType::NULLOBJ;
tsepez41a53ad2016-03-28 16:59:30 -0700179 m_arrayGlobalData.push_back(std::move(pNewData));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700180}
181
tsepez4cf55152016-11-02 14:37:54 -0700182bool CJS_GlobalData::SetGlobalVariablePersistent(const CFX_ByteString& propname,
183 bool bPersistent) {
tsepez24a48882016-04-11 15:18:40 -0700184 CFX_ByteString sPropName(propname);
185 if (!TrimPropName(&sPropName))
tsepez4cf55152016-11-02 14:37:54 -0700186 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700187
tsepez41a53ad2016-03-28 16:59:30 -0700188 CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName);
189 if (!pData)
tsepez4cf55152016-11-02 14:37:54 -0700190 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700191
tsepez41a53ad2016-03-28 16:59:30 -0700192 pData->bPersistent = bPersistent;
tsepez4cf55152016-11-02 14:37:54 -0700193 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700194}
195
tsepez4cf55152016-11-02 14:37:54 -0700196bool CJS_GlobalData::DeleteGlobalVariable(const CFX_ByteString& propname) {
tsepez24a48882016-04-11 15:18:40 -0700197 CFX_ByteString sPropName(propname);
198 if (!TrimPropName(&sPropName))
tsepez4cf55152016-11-02 14:37:54 -0700199 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700200
tsepez41a53ad2016-03-28 16:59:30 -0700201 auto iter = FindGlobalVariable(sPropName);
202 if (iter == m_arrayGlobalData.end())
tsepez4cf55152016-11-02 14:37:54 -0700203 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700204
tsepez41a53ad2016-03-28 16:59:30 -0700205 m_arrayGlobalData.erase(iter);
tsepez4cf55152016-11-02 14:37:54 -0700206 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700207}
208
209int32_t CJS_GlobalData::GetSize() const {
tsepez41a53ad2016-03-28 16:59:30 -0700210 return pdfium::CollectionSize<int32_t>(m_arrayGlobalData);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700211}
212
213CJS_GlobalData_Element* CJS_GlobalData::GetAt(int index) const {
tsepez41a53ad2016-03-28 16:59:30 -0700214 if (index < 0 || index >= GetSize())
215 return nullptr;
216 return m_arrayGlobalData[index].get();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700217}
218
219void CJS_GlobalData::LoadGlobalPersistentVariables() {
thestig1cd352e2016-06-07 17:53:06 -0700220 uint8_t* pBuffer = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700221 int32_t nLength = 0;
222
223 LoadFileBuffer(m_sFilePath.c_str(), pBuffer, nLength);
224 CRYPT_ArcFourCryptBlock(pBuffer, nLength, JS_RC4KEY, sizeof(JS_RC4KEY));
225
226 if (pBuffer) {
227 uint8_t* p = pBuffer;
Tom Sepez62a70f92016-03-21 15:00:20 -0700228 uint16_t wType = *((uint16_t*)p);
229 p += sizeof(uint16_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700230
Tom Sepez62a70f92016-03-21 15:00:20 -0700231 if (wType == (uint16_t)(('X' << 8) | 'F')) {
232 uint16_t wVersion = *((uint16_t*)p);
233 p += sizeof(uint16_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700234
235 ASSERT(wVersion <= 2);
236
tsepezc3255f52016-03-25 14:52:27 -0700237 uint32_t dwCount = *((uint32_t*)p);
238 p += sizeof(uint32_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700239
tsepezc3255f52016-03-25 14:52:27 -0700240 uint32_t dwSize = *((uint32_t*)p);
241 p += sizeof(uint32_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700242
tsepezc3255f52016-03-25 14:52:27 -0700243 if (dwSize == nLength - sizeof(uint16_t) * 2 - sizeof(uint32_t) * 2) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700244 for (int32_t i = 0, sz = dwCount; i < sz; i++) {
245 if (p > pBuffer + nLength)
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700246 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700247
tsepezc3255f52016-03-25 14:52:27 -0700248 uint32_t dwNameLen = *((uint32_t*)p);
249 p += sizeof(uint32_t);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700250
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700251 if (p + dwNameLen > pBuffer + nLength)
252 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700253
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700254 CFX_ByteString sEntry = CFX_ByteString(p, dwNameLen);
255 p += sizeof(char) * dwNameLen;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700256
weili47228ac2016-07-20 10:35:31 -0700257 JS_GlobalDataType wDataType =
258 static_cast<JS_GlobalDataType>(*((uint16_t*)p));
Tom Sepez62a70f92016-03-21 15:00:20 -0700259 p += sizeof(uint16_t);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700260
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700261 switch (wDataType) {
weili47228ac2016-07-20 10:35:31 -0700262 case JS_GlobalDataType::NUMBER: {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700263 double dData = 0;
264 switch (wVersion) {
265 case 1: {
tsepezc3255f52016-03-25 14:52:27 -0700266 uint32_t dwData = *((uint32_t*)p);
267 p += sizeof(uint32_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700268 dData = dwData;
269 } break;
270 case 2: {
271 dData = *((double*)p);
272 p += sizeof(double);
273 } break;
274 }
275 SetGlobalVariableNumber(sEntry, dData);
tsepez4cf55152016-11-02 14:37:54 -0700276 SetGlobalVariablePersistent(sEntry, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700277 } break;
weili47228ac2016-07-20 10:35:31 -0700278 case JS_GlobalDataType::BOOLEAN: {
Tom Sepez62a70f92016-03-21 15:00:20 -0700279 uint16_t wData = *((uint16_t*)p);
280 p += sizeof(uint16_t);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700281 SetGlobalVariableBoolean(sEntry, (bool)(wData == 1));
tsepez4cf55152016-11-02 14:37:54 -0700282 SetGlobalVariablePersistent(sEntry, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700283 } break;
weili47228ac2016-07-20 10:35:31 -0700284 case JS_GlobalDataType::STRING: {
tsepezc3255f52016-03-25 14:52:27 -0700285 uint32_t dwLength = *((uint32_t*)p);
286 p += sizeof(uint32_t);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700287
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700288 if (p + dwLength > pBuffer + nLength)
289 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700290
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700291 SetGlobalVariableString(sEntry, CFX_ByteString(p, dwLength));
tsepez4cf55152016-11-02 14:37:54 -0700292 SetGlobalVariablePersistent(sEntry, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700293 p += sizeof(char) * dwLength;
294 } break;
weili47228ac2016-07-20 10:35:31 -0700295 case JS_GlobalDataType::NULLOBJ: {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700296 SetGlobalVariableNull(sEntry);
tsepez4cf55152016-11-02 14:37:54 -0700297 SetGlobalVariablePersistent(sEntry, true);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700298 }
weili47228ac2016-07-20 10:35:31 -0700299 case JS_GlobalDataType::OBJECT:
300 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700301 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700302 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700303 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700304 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700305 FX_Free(pBuffer);
306 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700307}
308
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700309void CJS_GlobalData::SaveGlobalPersisitentVariables() {
tsepezc3255f52016-03-25 14:52:27 -0700310 uint32_t nCount = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700311 CFX_BinaryBuf sData;
tsepez41a53ad2016-03-28 16:59:30 -0700312 for (const auto& pElement : m_arrayGlobalData) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700313 if (pElement->bPersistent) {
314 CFX_BinaryBuf sElement;
315 MakeByteString(pElement->data.sKey, &pElement->data, sElement);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700316 if (sData.GetSize() + sElement.GetSize() > JS_MAXGLOBALDATA)
317 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700318
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700319 sData.AppendBlock(sElement.GetBuffer(), sElement.GetSize());
320 nCount++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700321 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700322 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700323
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700324 CFX_BinaryBuf sFile;
Tom Sepez62a70f92016-03-21 15:00:20 -0700325 uint16_t wType = (uint16_t)(('X' << 8) | 'F');
326 sFile.AppendBlock(&wType, sizeof(uint16_t));
327 uint16_t wVersion = 2;
328 sFile.AppendBlock(&wVersion, sizeof(uint16_t));
tsepezc3255f52016-03-25 14:52:27 -0700329 sFile.AppendBlock(&nCount, sizeof(uint32_t));
330 uint32_t dwSize = sData.GetSize();
331 sFile.AppendBlock(&dwSize, sizeof(uint32_t));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700332
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700333 sFile.AppendBlock(sData.GetBuffer(), sData.GetSize());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700334
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700335 CRYPT_ArcFourCryptBlock(sFile.GetBuffer(), sFile.GetSize(), JS_RC4KEY,
336 sizeof(JS_RC4KEY));
337 WriteFileBuffer(m_sFilePath.c_str(), (const FX_CHAR*)sFile.GetBuffer(),
338 sFile.GetSize());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700339}
340
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700341void CJS_GlobalData::LoadFileBuffer(const FX_WCHAR* sFilePath,
342 uint8_t*& pBuffer,
343 int32_t& nLength) {
344 // UnSupport.
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700345}
346
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700347void CJS_GlobalData::WriteFileBuffer(const FX_WCHAR* sFilePath,
348 const FX_CHAR* pBuffer,
349 int32_t nLength) {
350 // UnSupport.
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700351}
352
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700353void CJS_GlobalData::MakeByteString(const CFX_ByteString& name,
354 CJS_KeyValue* pData,
355 CFX_BinaryBuf& sData) {
weili47228ac2016-07-20 10:35:31 -0700356 switch (pData->nType) {
357 case JS_GlobalDataType::NUMBER: {
tsepezc3255f52016-03-25 14:52:27 -0700358 uint32_t dwNameLen = (uint32_t)name.GetLength();
359 sData.AppendBlock(&dwNameLen, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700360 sData.AppendString(name);
weili47228ac2016-07-20 10:35:31 -0700361 sData.AppendBlock(&pData->nType, sizeof(uint16_t));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700362
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700363 double dData = pData->dData;
364 sData.AppendBlock(&dData, sizeof(double));
365 } break;
weili47228ac2016-07-20 10:35:31 -0700366 case JS_GlobalDataType::BOOLEAN: {
tsepezc3255f52016-03-25 14:52:27 -0700367 uint32_t dwNameLen = (uint32_t)name.GetLength();
368 sData.AppendBlock(&dwNameLen, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700369 sData.AppendString(name);
weili47228ac2016-07-20 10:35:31 -0700370 sData.AppendBlock(&pData->nType, sizeof(uint16_t));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700371
Tom Sepez62a70f92016-03-21 15:00:20 -0700372 uint16_t wData = (uint16_t)pData->bData;
373 sData.AppendBlock(&wData, sizeof(uint16_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700374 } break;
weili47228ac2016-07-20 10:35:31 -0700375 case JS_GlobalDataType::STRING: {
tsepezc3255f52016-03-25 14:52:27 -0700376 uint32_t dwNameLen = (uint32_t)name.GetLength();
377 sData.AppendBlock(&dwNameLen, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700378 sData.AppendString(name);
weili47228ac2016-07-20 10:35:31 -0700379 sData.AppendBlock(&pData->nType, sizeof(uint16_t));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700380
tsepezc3255f52016-03-25 14:52:27 -0700381 uint32_t dwDataLen = (uint32_t)pData->sData.GetLength();
382 sData.AppendBlock(&dwDataLen, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700383 sData.AppendString(pData->sData);
384 } break;
weili47228ac2016-07-20 10:35:31 -0700385 case JS_GlobalDataType::NULLOBJ: {
tsepezc3255f52016-03-25 14:52:27 -0700386 uint32_t dwNameLen = (uint32_t)name.GetLength();
387 sData.AppendBlock(&dwNameLen, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700388 sData.AppendString(name);
weili47228ac2016-07-20 10:35:31 -0700389 sData.AppendBlock(&pData->nType, sizeof(uint32_t));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700390 } break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700391 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700392 break;
393 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700394}