• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #define PRINT_FORMAT_LEVEL_MAX 500
27 }
28 
GetItemFromArray(const CJson * jsonArr,int32_t index)29 CJson* GetItemFromArray(const CJson* jsonArr, int32_t index)
30 {
31     if (jsonArr == nullptr) {
32         return nullptr;
33     }
34     return cJSON_GetArrayItem(jsonArr, index);
35 }
36 
CreateJsonFromString(const std::string & jsonStr)37 CJsonUnique CreateJsonFromString(const std::string& jsonStr)
38 {
39     if (jsonStr.empty()) {
40         return nullptr;
41     }
42     CJsonUnique aPtr(cJSON_Parse(jsonStr.c_str()), FreeJson);
43     return aPtr;
44 }
45 
CreateJson(void)46 CJsonUnique CreateJson(void)
47 {
48     CJsonUnique aPtr(cJSON_CreateObject(), FreeJson);
49     return aPtr;
50 }
51 
CreateJsonArray(void)52 CJsonUnique CreateJsonArray(void)
53 {
54     CJsonUnique aPtr(cJSON_CreateArray(), FreeJson);
55     return aPtr;
56 }
57 
CreateJsonString(const std::string & value)58 CJsonUnique CreateJsonString(const std::string& value)
59 {
60     CJsonUnique aPtr(cJSON_CreateString(value.c_str()), FreeJson);
61     return aPtr;
62 }
63 
FreeJson(CJson * jsonObj)64 void FreeJson(CJson* jsonObj)
65 {
66     cJSON_Delete(jsonObj);
67     jsonObj = nullptr;
68 }
69 
PackJsonToString(const CJson * jsonObj)70 std::string PackJsonToString(const CJson* jsonObj)
71 {
72     char* ptr = cJSON_PrintUnformatted(jsonObj);
73     if (ptr == nullptr) {
74         return std::string();
75     }
76     std::string ret = std::string(ptr);
77     FreeJsonString(ptr);
78     return ret;
79 }
80 
PackJsonToString(const CJsonUnique & jsonObj)81 std::string PackJsonToString(const CJsonUnique& jsonObj)
82 {
83     return PackJsonToString(jsonObj.get());
84 }
85 
GetTabContentString(uint32_t level)86 static std::string GetTabContentString(uint32_t level)
87 {
88     std::string str = "";
89     for (uint32_t i = 0; i < level; ++i) {
90         str += " ";
91     }
92     return str;
93 }
94 
JsonToStringFormatted(const CJson * jsonObj,uint32_t level)95 std::string JsonToStringFormatted(const CJson* jsonObj, uint32_t level)
96 {
97     if (jsonObj == nullptr || level > PRINT_FORMAT_LEVEL_MAX) {
98         return "";
99     }
100     std::string str = "";
101     CJson* child = nullptr;
102     switch (jsonObj->type) {
103         case cJSON_Object:
104             str += GetTabContentString(level) + "{\n";
105             child = jsonObj->child;
106             while (child != nullptr) {
107                 str += GetTabContentString(level + 2) + "\"" + std::string(child->string) + "\": "; // 2: space
108                 str += JsonToStringFormatted(child, level + 2); // 2: space
109                 str += (child->next != nullptr) ? ",\n" : "\n";
110                 child = child->next;
111             }
112             str += GetTabContentString(level) + "}";
113             break;
114         case cJSON_Array:
115             str += "[\n";
116             child = jsonObj->child;
117             while (child != nullptr) {
118                 str += JsonToStringFormatted(child, level + 2); // 2: space
119                 str += (child->next != nullptr) ? ",\n" : "\n";
120                 child = child->next;
121             }
122             str += GetTabContentString(level) + "]";
123             break;
124         case cJSON_String:
125             str += "\"" + std::string(jsonObj->valuestring) + "\"";
126             break;
127         case cJSON_Number:
128             str += std::to_string(static_cast<int64_t>(jsonObj->valuedouble));
129             break;
130         case cJSON_True:
131             str += "true";
132             break;
133         case cJSON_False:
134             str += "false";
135             break;
136         default:
137             str += "unkown type";
138             break;
139     }
140     return str;
141 }
142 
FreeJsonString(char * jsonStr)143 void FreeJsonString(char* jsonStr)
144 {
145     if (jsonStr != nullptr) {
146         cJSON_free(jsonStr);
147     }
148 }
149 
GetObjFromJson(const CJson * jsonObj,const std::string & key)150 CJson* GetObjFromJson(const CJson* jsonObj, const std::string& key)
151 {
152     if ((jsonObj == nullptr) || key.empty()) {
153         return nullptr;
154     }
155 
156     CJson* objValue = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
157     if (objValue != nullptr && cJSON_IsObject(objValue)) {
158         return objValue;
159     }
160     return nullptr;
161 }
162 
GetObjFromJson(CJsonUnique & jsonObj,const std::string & key)163 CJson* GetObjFromJson(CJsonUnique& jsonObj, const std::string& key)
164 {
165     return GetObjFromJson(jsonObj.get(), key);
166 }
167 
GetArrayFromJson(const CJson * jsonObj,const std::string & key)168 CJson* GetArrayFromJson(const CJson* jsonObj, const std::string& key)
169 {
170     if ((jsonObj == nullptr) || key.empty()) {
171         return nullptr;
172     }
173 
174     CJson* objValue = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
175     if (objValue != nullptr && cJSON_IsArray(objValue)) {
176         return objValue;
177     }
178     return nullptr;
179 }
180 
GetArrayFromJson(CJsonUnique & jsonObj,const std::string & key)181 CJson* GetArrayFromJson(CJsonUnique& jsonObj, const std::string& key)
182 {
183     return GetArrayFromJson(jsonObj.get(), key);
184 }
185 
GetArrayFromJson(const CJson * jsonObj,const std::string & key,std::vector<std::string> & out)186 bool GetArrayFromJson(const CJson* jsonObj, const std::string& key, std::vector<std::string>& out)
187 {
188     if (jsonObj == nullptr || key.empty()) {
189         return false;
190     }
191 
192     cJSON* stringArray = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
193     if (stringArray != nullptr && cJSON_IsArray(stringArray)) {
194         int32_t arraySize = cJSON_GetArraySize(stringArray);
195         for (int32_t i = 0; i < arraySize; i++) {
196             CJson* stringItem = cJSON_GetArrayItem(stringArray, i);
197             if (stringItem != nullptr && cJSON_IsString(stringItem)) {
198                 out.emplace_back(cJSON_GetStringValue(stringItem));
199             }
200         }
201         return true;
202     }
203     return false;
204 }
205 
GetStringFromJson(const CJson * jsonObj,const std::string & key,std::string & out)206 bool GetStringFromJson(const CJson* jsonObj, const std::string& key, std::string& out)
207 {
208     if (jsonObj == nullptr || key.empty()) {
209         return false;
210     }
211 
212     cJSON* jsonObjTmp = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
213     if (jsonObjTmp != nullptr && cJSON_IsString(jsonObjTmp)) {
214         out = cJSON_GetStringValue(jsonObjTmp);
215         return true;
216     }
217     return false;
218 }
219 
GetIntFromJson(const CJson * jsonObj,const std::string & key,int32_t & value)220 bool GetIntFromJson(const CJson* jsonObj, const std::string& key, int32_t& value)
221 {
222     if ((jsonObj == nullptr) || key.empty()) {
223         return false;
224     }
225 
226     CJson* jsonObjTmp = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
227     if (jsonObjTmp != nullptr && cJSON_IsNumber(jsonObjTmp)) {
228         value = static_cast<int>(cJSON_GetNumberValue(jsonObjTmp));
229         return true;
230     }
231     return false;
232 }
233 
GetIntFromJson(const CJsonUnique & jsonObj,const std::string & key,int32_t & value)234 bool GetIntFromJson(const CJsonUnique& jsonObj, const std::string& key, int32_t& value)
235 {
236     return GetIntFromJson(jsonObj.get(), key, value);
237 }
238 
GetUnsignedIntFromJson(const CJson * jsonObj,const std::string & key,uint32_t & value)239 bool GetUnsignedIntFromJson(const CJson* jsonObj, const std::string& key, uint32_t& value)
240 {
241     if ((jsonObj == nullptr) || key.empty()) {
242         return false;
243     }
244 
245     CJson* jsonObjTmp = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
246     if (jsonObjTmp != nullptr && cJSON_IsNumber(jsonObjTmp)) {
247         value = static_cast<uint32_t>(cJSON_GetNumberValue(jsonObjTmp));
248         return true;
249     }
250     return false;
251 }
252 
GetUnsignedIntFromJson(const CJsonUnique & jsonObj,const std::string & key,uint32_t & value)253 bool GetUnsignedIntFromJson(const CJsonUnique& jsonObj, const std::string& key, uint32_t& value)
254 {
255     return GetUnsignedIntFromJson(jsonObj.get(), key, value);
256 }
257 
GetBoolFromJson(const CJson * jsonObj,const std::string & key,bool & value)258 bool GetBoolFromJson(const CJson* jsonObj, const std::string& key, bool& value)
259 {
260     if ((jsonObj == nullptr) || key.empty()) {
261         return false;
262     }
263 
264     CJson* jsonObjTmp = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
265     if (jsonObjTmp != nullptr && cJSON_IsBool(jsonObjTmp)) {
266         value = cJSON_IsTrue(jsonObjTmp) ? true : false;
267         return true;
268     }
269     return false;
270 }
271 
GetBoolFromJson(const CJsonUnique & jsonObj,const std::string & key,bool & value)272 bool GetBoolFromJson(const CJsonUnique& jsonObj, const std::string& key, bool& value)
273 {
274     return GetBoolFromJson(jsonObj.get(), key, value);
275 }
276 
AddObjToJson(CJson * jsonObj,const std::string & key,const CJson * childObj)277 bool AddObjToJson(CJson* jsonObj, const std::string& key, const CJson* childObj)
278 {
279     if ((jsonObj == nullptr) || key.empty() || (childObj == nullptr)) {
280         return false;
281     }
282 
283     CJson* tmpObj = cJSON_Duplicate(childObj, RECURSE_FLAG_TRUE);
284     if (tmpObj == nullptr) {
285         return false;
286     }
287 
288     CJson* objInJson = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
289     if (objInJson == nullptr) {
290         if (!cJSON_AddItemToObject(jsonObj, key.c_str(), tmpObj)) {
291             cJSON_Delete(tmpObj);
292             return false;
293         }
294     } else {
295         if (!cJSON_ReplaceItemInObjectCaseSensitive(jsonObj, key.c_str(), tmpObj)) {
296             cJSON_Delete(tmpObj);
297             return false;
298         }
299     }
300     return true;
301 }
302 
AddObjToJson(CJsonUnique & jsonObj,const std::string & key,CJsonUnique & childObj)303 bool AddObjToJson(CJsonUnique& jsonObj, const std::string& key, CJsonUnique& childObj)
304 {
305     return AddObjToJson(jsonObj.get(), key, childObj.get());
306 }
307 
AddObjToArray(CJson * jsonArr,CJson * item)308 bool AddObjToArray(CJson* jsonArr, CJson* item)
309 {
310     if ((jsonArr == nullptr) || (item == nullptr)) {
311         return false;
312     }
313 
314     if (!cJSON_IsArray(jsonArr)) {
315         return false;
316     }
317 
318     CJson* tmpObj = cJSON_Duplicate(item, RECURSE_FLAG_TRUE);
319     if (tmpObj == nullptr) {
320         return false;
321     }
322     return cJSON_AddItemToArray(jsonArr, tmpObj);
323 }
324 
AddObjToArray(CJsonUnique & jsonArr,CJsonUnique & item)325 bool AddObjToArray(CJsonUnique& jsonArr, CJsonUnique& item)
326 {
327     return AddObjToArray(jsonArr.get(), item.get());
328 }
329 
AddStringToJson(CJson * jsonObj,const std::string & key,const std::string & value)330 bool AddStringToJson(CJson* jsonObj, const std::string& key, const std::string& value)
331 {
332     if ((jsonObj == nullptr) || key.empty() || value.empty()) {
333         return false;
334     }
335 
336     CJson* objInJson = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
337     if (objInJson == nullptr) {
338         if (cJSON_AddStringToObject(jsonObj, key.c_str(), value.c_str()) == nullptr) {
339             return false;
340         }
341     } else {
342         CJson* tmp = cJSON_CreateString(value.c_str());
343         if (tmp == nullptr) {
344             return false;
345         }
346         if (!cJSON_ReplaceItemInObjectCaseSensitive(jsonObj, key.c_str(), tmp)) {
347             cJSON_Delete(tmp);
348             return false;
349         }
350     }
351 
352     return true;
353 }
354 
AddStringToJson(CJsonUnique & jsonObj,const std::string & key,const std::string & value)355 bool AddStringToJson(CJsonUnique& jsonObj, const std::string& key, const std::string& value)
356 {
357     return AddStringToJson(jsonObj.get(), key, value);
358 }
359 
AddBoolToJson(CJson * jsonObj,const std::string & key,bool value)360 bool AddBoolToJson(CJson* jsonObj, const std::string& key, bool value)
361 {
362     if ((jsonObj == nullptr) || key.empty()) {
363         return false;
364     }
365 
366     CJson* objInJson = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
367     if (objInJson == nullptr) {
368         if (cJSON_AddBoolToObject(jsonObj, key.c_str(), value) == nullptr) {
369             return false;
370         }
371     } else {
372         CJson* tmp = cJSON_CreateBool(value);
373         if (tmp == nullptr) {
374             return false;
375         }
376         if (!cJSON_ReplaceItemInObjectCaseSensitive(jsonObj, key.c_str(), tmp)) {
377             cJSON_Delete(tmp);
378             return false;
379         }
380     }
381 
382     return true;
383 }
384 
AddBoolToJson(CJsonUnique & jsonObj,const std::string & key,bool value)385 bool AddBoolToJson(CJsonUnique& jsonObj, const std::string& key, bool value)
386 {
387     return AddBoolToJson(jsonObj.get(), key, value);
388 }
389 
AddIntToJson(CJson * jsonObj,const std::string & key,const int32_t value)390 bool AddIntToJson(CJson* jsonObj, const std::string& key, const int32_t value)
391 {
392     if ((jsonObj == nullptr) || key.empty()) {
393         return false;
394     }
395 
396     CJson* objInJson = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
397     if (objInJson == nullptr) {
398         if (cJSON_AddNumberToObject(jsonObj, key.c_str(), value) == nullptr) {
399             return false;
400         }
401     } else {
402         CJson* tmp = cJSON_CreateNumber(value);
403         if (tmp == nullptr) {
404             return false;
405         }
406         if (!cJSON_ReplaceItemInObjectCaseSensitive(jsonObj, key.c_str(), tmp)) {
407             cJSON_Delete(tmp);
408             return false;
409         }
410     }
411 
412     return true;
413 }
414 
AddIntToJson(CJsonUnique & jsonObj,const std::string & key,int32_t value)415 bool AddIntToJson(CJsonUnique& jsonObj, const std::string& key, int32_t value)
416 {
417     return AddIntToJson(jsonObj.get(), key, value);
418 }
419 
AddUnsignedIntToJson(CJson * jsonObj,const std::string & key,const uint32_t value)420 bool AddUnsignedIntToJson(CJson* jsonObj, const std::string& key, const uint32_t value)
421 {
422     if ((jsonObj == nullptr) || key.empty()) {
423         return false;
424     }
425 
426     CJson* objInJson = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
427     double tmpValue = static_cast<double>(value);
428     if (objInJson == nullptr) {
429         if (cJSON_AddNumberToObject(jsonObj, key.c_str(), tmpValue) == nullptr) {
430             return false;
431         }
432     } else {
433         CJson* tmp = cJSON_CreateNumber(tmpValue);
434         if (tmp == nullptr) {
435             return false;
436         }
437         if (!cJSON_ReplaceItemInObjectCaseSensitive(jsonObj, key.c_str(), tmp)) {
438             cJSON_Delete(tmp);
439             return false;
440         }
441     }
442     return true;
443 }
444 
AddUnsignedIntToJson(CJsonUnique & jsonObj,const std::string & key,uint32_t value)445 bool AddUnsignedIntToJson(CJsonUnique& jsonObj, const std::string& key, uint32_t value)
446 {
447     return AddUnsignedIntToJson(jsonObj.get(), key, value);
448 }
449 
AddInt64ToJson(CJson * jsonObj,const std::string & key,int64_t value)450 bool AddInt64ToJson(CJson* jsonObj, const std::string& key, int64_t value)
451 {
452     if ((jsonObj == nullptr) || key.empty()) {
453         return false;
454     }
455 
456     CJson* objInJson = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
457     double tmpValue = static_cast<double>(value);
458     if (objInJson == nullptr) {
459         if (cJSON_AddNumberToObject(jsonObj, key.c_str(), tmpValue) == nullptr) {
460             return false;
461         }
462     } else {
463         CJson* tmp = cJSON_CreateNumber(tmpValue);
464         if (tmp == nullptr) {
465             return false;
466         }
467         if (!cJSON_ReplaceItemInObjectCaseSensitive(jsonObj, key.c_str(), tmp)) {
468             cJSON_Delete(tmp);
469             return false;
470         }
471     }
472     return true;
473 }
474 
AddInt64ToJson(CJsonUnique & jsonObj,const std::string & key,int64_t value)475 bool AddInt64ToJson(CJsonUnique& jsonObj, const std::string& key, int64_t value)
476 {
477     return AddInt64ToJson(jsonObj.get(), key, value);
478 }
479 }  // namespace AccessToken
480 }  // namespace Security
481 }  // namespace OHOS