1 /*
2 * Copyright (C) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "cjson_utils.h"
17 #include <cstdint>
18 #include <memory>
19 #include <string>
20
21 namespace OHOS {
22 namespace Security {
23 namespace AccessToken {
24 namespace {
25 #define RECURSE_FLAG_TRUE 1
26 }
27
GetItemFromArray(const CJson * jsonArr,int32_t index)28 CJson *GetItemFromArray(const CJson* jsonArr, int32_t index)
29 {
30 if (jsonArr == nullptr) {
31 return nullptr;
32 }
33 return cJSON_GetArrayItem(jsonArr, index);
34 }
35
CreateJsonFromString(const std::string & jsonStr)36 CJsonUnique CreateJsonFromString(const std::string& jsonStr)
37 {
38 if (jsonStr.empty()) {
39 return nullptr;
40 }
41 CJsonUnique aPtr(cJSON_Parse(jsonStr.c_str()), FreeJson);
42 return aPtr;
43 }
44
CreateJson(void)45 CJsonUnique CreateJson(void)
46 {
47 CJsonUnique aPtr(cJSON_CreateObject(), FreeJson);
48 return aPtr;
49 }
50
CreateJsonArray(void)51 CJsonUnique CreateJsonArray(void)
52 {
53 CJsonUnique aPtr(cJSON_CreateArray(), FreeJson);
54 return aPtr;
55 }
56
FreeJson(CJson * jsonObj)57 void FreeJson(CJson* jsonObj)
58 {
59 cJSON_Delete(jsonObj);
60 jsonObj = nullptr;
61 }
62
PackJsonToString(const CJson * jsonObj)63 std::string PackJsonToString(const CJson* jsonObj)
64 {
65 char* ptr = cJSON_PrintUnformatted(jsonObj);
66 if (ptr == nullptr) {
67 return std::string();
68 }
69 std::string ret = std::string(ptr);
70 FreeJsonString(ptr);
71 return ret;
72 }
73
PackJsonToString(const CJsonUnique & jsonObj)74 std::string PackJsonToString(const CJsonUnique& jsonObj)
75 {
76 return PackJsonToString(jsonObj.get());
77 }
78
FreeJsonString(char * jsonStr)79 void FreeJsonString(char* jsonStr)
80 {
81 if (jsonStr != nullptr) {
82 cJSON_free(jsonStr);
83 }
84 }
85
GetObjFromJson(const CJson * jsonObj,const std::string & key)86 CJson* GetObjFromJson(const CJson* jsonObj, const std::string& key)
87 {
88 if (key.empty()) {
89 return nullptr;
90 }
91
92 CJson* objValue = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
93 if (objValue != nullptr && cJSON_IsObject(objValue)) {
94 return objValue;
95 }
96 return nullptr;
97 }
98
GetObjFromJson(CJsonUnique & jsonObj,const std::string & key)99 CJson* GetObjFromJson(CJsonUnique& jsonObj, const std::string& key)
100 {
101 return GetObjFromJson(jsonObj.get(), key);
102 }
103
GetArrayFromJson(const CJson * jsonObj,const std::string & key)104 CJson* GetArrayFromJson(const CJson* jsonObj, const std::string& key)
105 {
106 if (key.empty()) {
107 return nullptr;
108 }
109
110 CJson* objValue = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
111 if (objValue != nullptr && cJSON_IsArray(objValue)) {
112 return objValue;
113 }
114 return nullptr;
115 }
116
GetArrayFromJson(CJsonUnique & jsonObj,const std::string & key)117 CJson* GetArrayFromJson(CJsonUnique& jsonObj, const std::string& key)
118 {
119 return GetArrayFromJson(jsonObj.get(), key);
120 }
121
GetStringFromJson(const CJson * jsonObj,const std::string & key,std::string & out)122 bool GetStringFromJson(const CJson *jsonObj, const std::string& key, std::string& out)
123 {
124 if (jsonObj == nullptr || key.empty()) {
125 return false;
126 }
127
128 cJSON *jsonObjTmp = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
129 if (jsonObjTmp != nullptr && cJSON_IsString(jsonObjTmp)) {
130 out = cJSON_GetStringValue(jsonObjTmp);
131 return true;
132 }
133 return false;
134 }
135
GetIntFromJson(const CJson * jsonObj,const std::string & key,int32_t & value)136 bool GetIntFromJson(const CJson* jsonObj, const std::string& key, int32_t& value)
137 {
138 if (key.empty()) {
139 return false;
140 }
141
142 CJson* jsonObjTmp = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
143 if (jsonObjTmp != nullptr && cJSON_IsNumber(jsonObjTmp)) {
144 value = static_cast<int>(cJSON_GetNumberValue(jsonObjTmp));
145 return true;
146 }
147 return false;
148 }
149
GetIntFromJson(const CJsonUnique & jsonObj,const std::string & key,int32_t & value)150 bool GetIntFromJson(const CJsonUnique& jsonObj, const std::string& key, int32_t& value)
151 {
152 return GetIntFromJson(jsonObj.get(), key, value);
153 }
154
GetUnsignedIntFromJson(const CJson * jsonObj,const std::string & key,uint32_t & value)155 bool GetUnsignedIntFromJson(const CJson* jsonObj, const std::string& key, uint32_t& value)
156 {
157 if (key.empty()) {
158 return false;
159 }
160
161 CJson* jsonObjTmp = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
162 if (jsonObjTmp != nullptr && cJSON_IsNumber(jsonObjTmp)) {
163 value = static_cast<uint32_t>(cJSON_GetNumberValue(jsonObjTmp));
164 return true;
165 }
166 return false;
167 }
168
GetUnsignedIntFromJson(const CJsonUnique & jsonObj,const std::string & key,uint32_t & value)169 bool GetUnsignedIntFromJson(const CJsonUnique& jsonObj, const std::string& key, uint32_t& value)
170 {
171 return GetUnsignedIntFromJson(jsonObj.get(), key, value);
172 }
173
GetBoolFromJson(const CJson * jsonObj,const std::string & key,bool & value)174 bool GetBoolFromJson(const CJson* jsonObj, const std::string& key, bool& value)
175 {
176 if (key.empty()) {
177 return false;
178 }
179
180 CJson* jsonObjTmp = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
181 if (jsonObjTmp != nullptr && cJSON_IsBool(jsonObjTmp)) {
182 value = cJSON_IsTrue(jsonObjTmp) ? true : false;
183 return true;
184 }
185 return false;
186 }
187
GetBoolFromJson(const CJsonUnique & jsonObj,const std::string & key,bool & value)188 bool GetBoolFromJson(const CJsonUnique& jsonObj, const std::string& key, bool& value)
189 {
190 return GetBoolFromJson(jsonObj.get(), key, value);
191 }
192
AddObjToJson(CJson * jsonObj,const std::string & key,const CJson * childObj)193 bool AddObjToJson(CJson* jsonObj, const std::string& key, const CJson* childObj)
194 {
195 if (key.empty() || childObj == nullptr) {
196 return false;
197 }
198
199 CJson* tmpObj = cJSON_Duplicate(childObj, RECURSE_FLAG_TRUE);
200 if (tmpObj == nullptr) {
201 return false;
202 }
203
204 CJson* objInJson = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
205 if (objInJson == nullptr) {
206 if (!cJSON_AddItemToObject(jsonObj, key.c_str(), tmpObj)) {
207 cJSON_Delete(tmpObj);
208 return false;
209 }
210 } else {
211 if (!cJSON_ReplaceItemInObjectCaseSensitive(jsonObj, key.c_str(), tmpObj)) {
212 cJSON_Delete(tmpObj);
213 return false;
214 }
215 }
216 return true;
217 }
218
AddObjToJson(CJsonUnique & jsonObj,const std::string & key,CJsonUnique & childObj)219 bool AddObjToJson(CJsonUnique& jsonObj, const std::string& key, CJsonUnique& childObj)
220 {
221 return AddObjToJson(jsonObj.get(), key, childObj.get());
222 }
223
AddObjToArray(CJson * jsonArr,CJson * item)224 bool AddObjToArray(CJson* jsonArr, CJson* item)
225 {
226 if (item == nullptr) {
227 return false;
228 }
229
230 if (!cJSON_IsArray(jsonArr)) {
231 return false;
232 }
233
234 CJson* tmpObj = cJSON_Duplicate(item, RECURSE_FLAG_TRUE);
235 if (tmpObj == nullptr) {
236 return false;
237 }
238
239 bool ret = cJSON_AddItemToArray(jsonArr, tmpObj);
240 return ret;
241 }
242
AddObjToArray(CJsonUnique & jsonArr,CJsonUnique & item)243 bool AddObjToArray(CJsonUnique& jsonArr, CJsonUnique& item)
244 {
245 return AddObjToArray(jsonArr.get(), item.get());
246 }
247
AddStringToJson(CJson * jsonObj,const std::string & key,const std::string & value)248 bool AddStringToJson(CJson* jsonObj, const std::string& key, const std::string& value)
249 {
250 if (key.empty() || value.empty()) {
251 return false;
252 }
253
254 CJson* objInJson = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
255 if (objInJson == nullptr) {
256 if (cJSON_AddStringToObject(jsonObj, key.c_str(), value.c_str()) == nullptr) {
257 return false;
258 }
259 } else {
260 CJson* tmp = cJSON_CreateString(value.c_str());
261 if (tmp == nullptr) {
262 return false;
263 }
264 if (!cJSON_ReplaceItemInObjectCaseSensitive(jsonObj, key.c_str(), tmp)) {
265 cJSON_Delete(tmp);
266 return false;
267 }
268 }
269
270 return true;
271 }
272
AddStringToJson(CJsonUnique & jsonObj,const std::string & key,const std::string & value)273 bool AddStringToJson(CJsonUnique& jsonObj, const std::string& key, const std::string& value)
274 {
275 return AddStringToJson(jsonObj.get(), key, value);
276 }
277
AddBoolToJson(CJson * jsonObj,const std::string & key,const bool value)278 bool AddBoolToJson(CJson* jsonObj, const std::string& key, const bool value)
279 {
280 if (key.empty()) {
281 return false;
282 }
283
284 CJson* objInJson = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
285 if (objInJson == nullptr) {
286 if (cJSON_AddBoolToObject(jsonObj, key.c_str(), value) == nullptr) {
287 return false;
288 }
289 } else {
290 CJson* tmp = cJSON_CreateBool(value);
291 if (tmp == nullptr) {
292 return false;
293 }
294 if (!cJSON_ReplaceItemInObjectCaseSensitive(jsonObj, key.c_str(), tmp)) {
295 cJSON_Delete(tmp);
296 return false;
297 }
298 }
299
300 return true;
301 }
302
AddBoolToJson(CJsonUnique & jsonObj,const std::string & key,const bool value)303 bool AddBoolToJson(CJsonUnique& jsonObj, const std::string& key, const bool value)
304 {
305 return AddBoolToJson(jsonObj.get(), key, value);
306 }
307
AddIntToJson(CJson * jsonObj,const std::string & key,const int value)308 bool AddIntToJson(CJson* jsonObj, const std::string& key, const int value)
309 {
310 if (key.empty()) {
311 return false;
312 }
313
314 CJson* objInJson = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
315 if (objInJson == nullptr) {
316 if (cJSON_AddNumberToObject(jsonObj, key.c_str(), value) == nullptr) {
317 return false;
318 }
319 } else {
320 CJson* tmp = cJSON_CreateNumber(value);
321 if (tmp == nullptr) {
322 return false;
323 }
324 if (!cJSON_ReplaceItemInObjectCaseSensitive(jsonObj, key.c_str(), tmp)) {
325 cJSON_Delete(tmp);
326 return false;
327 }
328 }
329
330 return true;
331 }
332
AddIntToJson(CJsonUnique & jsonObj,const std::string & key,const int value)333 bool AddIntToJson(CJsonUnique& jsonObj, const std::string& key, const int value)
334 {
335 return AddIntToJson(jsonObj.get(), key, value);
336 }
337
AddUnsignedIntToJson(CJson * jsonObj,const std::string & key,const uint32_t value)338 bool AddUnsignedIntToJson(CJson* jsonObj, const std::string& key, const uint32_t value)
339 {
340 if (key.empty()) {
341 return false;
342 }
343
344 CJson* objInJson = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
345 double tmpValue = static_cast<double>(value);
346 if (objInJson == nullptr) {
347 if (cJSON_AddNumberToObject(jsonObj, key.c_str(), tmpValue) == nullptr) {
348 return false;
349 }
350 } else {
351 CJson* tmp = cJSON_CreateNumber(tmpValue);
352 if (tmp == nullptr) {
353 return false;
354 }
355 if (!cJSON_ReplaceItemInObjectCaseSensitive(jsonObj, key.c_str(), tmp)) {
356 cJSON_Delete(tmp);
357 return false;
358 }
359 }
360 return true;
361 }
362
AddUnsignedIntToJson(CJsonUnique & jsonObj,const std::string & key,const uint32_t value)363 bool AddUnsignedIntToJson(CJsonUnique& jsonObj, const std::string& key, const uint32_t value)
364 {
365 return AddUnsignedIntToJson(jsonObj.get(), key, value);
366 }
367 } // namespace AccessToken
368 } // namespace Security
369 } // namespace OHOS