• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 "json_utils.h"
17 #include <inttypes.h>
18 #include <string.h>
19 #include "securec.h"
20 #include "clib_error.h"
21 #include "clib_types.h"
22 #include "string_util.h"
23 
24 #define RECURSE_FLAG_TRUE 1
25 
CreateJsonFromString(const char * jsonStr)26 CJson *CreateJsonFromString(const char *jsonStr)
27 {
28     if (jsonStr == NULL) {
29         return NULL;
30     }
31     return cJSON_Parse(jsonStr);
32 }
33 
CreateJson(void)34 CJson *CreateJson(void)
35 {
36     return cJSON_CreateObject();
37 }
38 
CreateJsonArray(void)39 CJson *CreateJsonArray(void)
40 {
41     return cJSON_CreateArray();
42 }
43 
DuplicateJson(const CJson * jsonObj)44 CJson *DuplicateJson(const CJson *jsonObj)
45 {
46     if (jsonObj == NULL) {
47         return NULL;
48     }
49     return cJSON_Duplicate(jsonObj, RECURSE_FLAG_TRUE);
50 }
51 
FreeJson(CJson * jsonObj)52 void FreeJson(CJson *jsonObj)
53 {
54     cJSON_Delete(jsonObj);
55 }
56 
DeleteItemFromJson(CJson * jsonObj,const char * key)57 void DeleteItemFromJson(CJson *jsonObj, const char *key)
58 {
59     if (jsonObj == NULL || key == NULL) {
60         return;
61     }
62     cJSON_DeleteItemFromObjectCaseSensitive(jsonObj, key);
63 }
64 
DeleteAllItemExceptOne(CJson * jsonObj,const char * key)65 void DeleteAllItemExceptOne(CJson *jsonObj, const char *key)
66 {
67     if (jsonObj == NULL || key == NULL) {
68         return;
69     }
70 
71     CJson *curItem = jsonObj->child;
72     CJson *nextItem = NULL;
73     while (curItem != NULL) {
74         nextItem = curItem->next;
75         if (strcmp(key, curItem->string) != 0) {
76             cJSON_Delete(cJSON_DetachItemViaPointer(jsonObj, curItem));
77         }
78         curItem = nextItem;
79     }
80 }
81 
DeleteAllItem(CJson * jsonObj)82 void DeleteAllItem(CJson *jsonObj)
83 {
84     if (jsonObj == NULL) {
85         return;
86     }
87 
88     CJson *curItem = jsonObj->child;
89     CJson *nextItem = NULL;
90     while (curItem != NULL) {
91         nextItem = curItem->next;
92         cJSON_Delete(cJSON_DetachItemViaPointer(jsonObj, curItem));
93         curItem = nextItem;
94     }
95 }
96 
DetachItemFromJson(CJson * jsonObj,const char * key)97 CJson *DetachItemFromJson(CJson *jsonObj, const char *key)
98 {
99     if (jsonObj == NULL || key == NULL) {
100         return NULL;
101     }
102 
103     return cJSON_DetachItemFromObjectCaseSensitive(jsonObj, key);
104 }
105 
PackJsonToString(const CJson * jsonObj)106 char *PackJsonToString(const CJson *jsonObj)
107 {
108     if (jsonObj == NULL) {
109         return NULL;
110     }
111     return cJSON_PrintUnformatted(jsonObj);
112 }
113 
FreeJsonString(char * jsonStr)114 void FreeJsonString(char *jsonStr)
115 {
116     cJSON_free(jsonStr);
117 }
118 
GetItemNum(const CJson * jsonObj)119 int GetItemNum(const CJson *jsonObj)
120 {
121     if (jsonObj == NULL) {
122         return 0;
123     }
124     return cJSON_GetArraySize(jsonObj);
125 }
126 
GetItemKey(const CJson * item)127 const char *GetItemKey(const CJson *item)
128 {
129     if (item == NULL) {
130         return NULL;
131     }
132     return item->string;
133 }
134 
GetObjFromJson(const CJson * jsonObj,const char * key)135 CJson *GetObjFromJson(const CJson *jsonObj, const char *key)
136 {
137     if (jsonObj == NULL || key == NULL) {
138         return NULL;
139     }
140 
141     cJSON *objValue = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
142     if (objValue != NULL) {
143         return objValue;
144     }
145 
146     int len = cJSON_GetArraySize(jsonObj);
147     for (int i = 0; i < len; i++) {
148         cJSON *item = cJSON_GetArrayItem(jsonObj, i);
149         if (cJSON_IsObject(item)) {
150             cJSON *obj = GetObjFromJson(item, key);
151             if (obj != NULL) {
152                 return obj;
153             }
154         }
155     }
156 
157     return NULL;
158 }
159 
GetItemFromArray(const CJson * jsonArr,int index)160 CJson *GetItemFromArray(const CJson *jsonArr, int index)
161 {
162     if (jsonArr == NULL) {
163         return NULL;
164     }
165     return cJSON_GetArrayItem(jsonArr, index);
166 }
167 
GetStringFromJson(const CJson * jsonObj,const char * key)168 const char *GetStringFromJson(const CJson *jsonObj, const char *key)
169 {
170     if (jsonObj == NULL || key == NULL) {
171         return NULL;
172     }
173 
174     cJSON *jsonObjTmp = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
175     if (jsonObjTmp != NULL && cJSON_IsString(jsonObjTmp)) {
176         return cJSON_GetStringValue(jsonObjTmp);
177     }
178 
179     int len = cJSON_GetArraySize(jsonObj);
180     for (int i = 0; i < len; i++) {
181         cJSON *item = cJSON_GetArrayItem(jsonObj, i);
182         if (cJSON_IsObject(item)) {
183             const char *resValue = GetStringFromJson(item, key);
184             if (resValue != NULL) {
185                 return resValue;
186             }
187         }
188     }
189 
190     return NULL;
191 }
192 
GetByteFromJson(const CJson * jsonObj,const char * key,uint8_t * byte,uint32_t len)193 int32_t GetByteFromJson(const CJson *jsonObj, const char *key, uint8_t *byte, uint32_t len)
194 {
195     if (jsonObj == NULL || key == NULL || byte == NULL) {
196         return CLIB_ERR_NULL_PTR;
197     }
198 
199     const char *valueStr = GetStringFromJson(jsonObj, key);
200     if (valueStr == NULL) {
201         return CLIB_ERR_JSON_GET;
202     }
203     if (len < strlen(valueStr) / BYTE_TO_HEX_OPER_LENGTH) {
204         return CLIB_ERR_INVALID_LEN;
205     }
206     return HexStringToByte(valueStr, byte, len);
207 }
208 
GetIntFromJson(const CJson * jsonObj,const char * key,int32_t * value)209 int32_t GetIntFromJson(const CJson *jsonObj, const char *key, int32_t *value)
210 {
211     if (jsonObj == NULL || key == NULL || value == NULL) {
212         return CLIB_ERR_NULL_PTR;
213     }
214 
215     cJSON *jsonObjTmp = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
216     if (jsonObjTmp != NULL && cJSON_IsNumber(jsonObjTmp)) {
217         *value = (int)cJSON_GetNumberValue(jsonObjTmp);
218         return CLIB_SUCCESS;
219     }
220 
221     int len = cJSON_GetArraySize(jsonObj);
222     for (int i = 0; i < len; i++) {
223         cJSON *item = cJSON_GetArrayItem(jsonObj, i);
224         if (cJSON_IsObject(item)) {
225             int32_t ret = GetIntFromJson(item, key, value);
226             if (ret == CLIB_SUCCESS) {
227                 return ret;
228             }
229         }
230     }
231 
232     return CLIB_ERR_JSON_GET;
233 }
234 
GetUnsignedIntFromJson(const CJson * jsonObj,const char * key,uint32_t * value)235 int32_t GetUnsignedIntFromJson(const CJson *jsonObj, const char *key, uint32_t *value)
236 {
237     if (jsonObj == NULL || key == NULL || value == NULL) {
238         return CLIB_ERR_NULL_PTR;
239     }
240 
241     cJSON *jsonObjTmp = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
242     if (jsonObjTmp != NULL && cJSON_IsNumber(jsonObjTmp)) {
243         double realValue = cJSON_GetNumberValue(jsonObjTmp);
244         if (realValue < 0) {
245             int32_t tmpValue = (int32_t)realValue;
246             *value = (uint32_t)tmpValue;
247         } else {
248             *value = (uint32_t)realValue;
249         }
250         return CLIB_SUCCESS;
251     }
252 
253     int len = cJSON_GetArraySize(jsonObj);
254     for (int i = 0; i < len; i++) {
255         cJSON *item = cJSON_GetArrayItem(jsonObj, i);
256         if (cJSON_IsObject(item)) {
257             int32_t ret = GetUnsignedIntFromJson(item, key, value);
258             if (ret == CLIB_SUCCESS) {
259                 return ret;
260             }
261         }
262     }
263 
264     return CLIB_ERR_JSON_GET;
265 }
266 
GetInt64FromJson(const CJson * jsonObj,const char * key,int64_t * value)267 int32_t GetInt64FromJson(const CJson *jsonObj, const char *key, int64_t *value)
268 {
269     const char *str = GetStringFromJson(jsonObj, key);
270     if (str == NULL) {
271         return CLIB_ERR_JSON_GET;
272     }
273     *value = StringToInt64(str);
274     return CLIB_SUCCESS;
275 }
276 
GetBoolFromJson(const CJson * jsonObj,const char * key,bool * value)277 int32_t GetBoolFromJson(const CJson *jsonObj, const char *key, bool *value)
278 {
279     if (jsonObj == NULL || key == NULL || value == NULL) {
280         return CLIB_ERR_NULL_PTR;
281     }
282 
283     cJSON *jsonObjTmp = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
284     if (jsonObjTmp != NULL && cJSON_IsBool(jsonObjTmp)) {
285         *value = cJSON_IsTrue(jsonObjTmp) ? true : false;
286         return CLIB_SUCCESS;
287     }
288 
289     int len = cJSON_GetArraySize(jsonObj);
290     for (int i = 0; i < len; i++) {
291         cJSON *item = cJSON_GetArrayItem(jsonObj, i);
292         if (cJSON_IsObject(item)) {
293             int32_t ret = GetBoolFromJson(item, key, value);
294             if (ret == CLIB_SUCCESS) {
295                 return ret;
296             }
297         }
298     }
299 
300     return CLIB_ERR_JSON_GET;
301 }
302 
GetStringValue(const CJson * item)303 char *GetStringValue(const CJson *item)
304 {
305     return cJSON_GetStringValue(item);
306 }
307 
AddObjToJson(CJson * jsonObj,const char * key,const CJson * childObj)308 int32_t AddObjToJson(CJson *jsonObj, const char *key, const CJson *childObj)
309 {
310     if (jsonObj == NULL || key == NULL || childObj == NULL) {
311         return CLIB_ERR_NULL_PTR;
312     }
313 
314     cJSON *tmpObj = cJSON_Duplicate(childObj, RECURSE_FLAG_TRUE);
315     if (tmpObj == NULL) {
316         return CLIB_ERR_JSON_DUPLICATE;
317     }
318 
319     cJSON *objInJson = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
320     if (objInJson == NULL) {
321         if (cJSON_AddItemToObject(jsonObj, key, tmpObj) == false) {
322             cJSON_Delete(tmpObj);
323             return CLIB_ERR_JSON_ADD;
324         }
325     } else {
326         if (cJSON_ReplaceItemInObjectCaseSensitive(jsonObj, key, tmpObj) == false) {
327             cJSON_Delete(tmpObj);
328             return CLIB_ERR_JSON_REPLACE;
329         }
330     }
331 
332     return CLIB_SUCCESS;
333 }
334 
AddObjToArray(CJson * jsonArr,CJson * item)335 int32_t AddObjToArray(CJson *jsonArr, CJson *item)
336 {
337     if (jsonArr == NULL || item == NULL) {
338         return CLIB_ERR_NULL_PTR;
339     }
340 
341     if (cJSON_IsArray(jsonArr) == false) {
342         return CLIB_ERR_INVALID_PARAM;
343     }
344 
345     bool ret = cJSON_AddItemToArray(jsonArr, item);
346     if (ret == false) {
347         return CLIB_ERR_JSON_ADD;
348     }
349 
350     return CLIB_SUCCESS;
351 }
352 
AddStringToArray(CJson * jsonArr,const char * string)353 int32_t AddStringToArray(CJson *jsonArr, const char *string)
354 {
355     if (jsonArr == NULL || string == NULL) {
356         return CLIB_ERR_NULL_PTR;
357     }
358 
359     if (cJSON_IsArray(jsonArr) == false) {
360         return CLIB_ERR_INVALID_PARAM;
361     }
362 
363     cJSON *strObj = cJSON_CreateString(string);
364     if (strObj == NULL) {
365         return CLIB_ERR_BAD_ALLOC;
366     }
367     bool ret = cJSON_AddItemToArray(jsonArr, strObj);
368     if (ret == false) {
369         cJSON_Delete(strObj);
370         return CLIB_ERR_JSON_ADD;
371     }
372 
373     return CLIB_SUCCESS;
374 }
375 
AddStringToJson(CJson * jsonObj,const char * key,const char * value)376 int32_t AddStringToJson(CJson *jsonObj, const char *key, const char *value)
377 {
378     if (jsonObj == NULL || key == NULL || value == NULL) {
379         return CLIB_ERR_NULL_PTR;
380     }
381 
382     cJSON *objInJson = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
383     if (objInJson == NULL) {
384         if (cJSON_AddStringToObject(jsonObj, key, value) == NULL) {
385             return CLIB_ERR_JSON_GET;
386         }
387     } else {
388         cJSON *tmp = cJSON_CreateString(value);
389         if (tmp == NULL) {
390             return CLIB_ERR_BAD_ALLOC;
391         }
392         if (cJSON_ReplaceItemInObjectCaseSensitive(jsonObj, key, tmp) == false) {
393             cJSON_Delete(tmp);
394             return CLIB_ERR_JSON_REPLACE;
395         }
396     }
397 
398     return CLIB_SUCCESS;
399 }
400 
AddByteToJson(CJson * jsonObj,const char * key,const uint8_t * byte,uint32_t len)401 int32_t AddByteToJson(CJson *jsonObj, const char *key, const uint8_t *byte, uint32_t len)
402 {
403     if (jsonObj == NULL || key == NULL || byte == NULL) {
404         return CLIB_ERR_NULL_PTR;
405     }
406 
407     uint32_t hexLen = len * BYTE_TO_HEX_OPER_LENGTH + 1;
408     char *hexStr = (char *)ClibMalloc(hexLen, 0);
409     if (hexStr == NULL) {
410         return CLIB_ERR_BAD_ALLOC;
411     }
412     int32_t ret = ByteToHexString(byte, len, hexStr, hexLen);
413     if (ret != CLIB_SUCCESS) {
414         ClibFree(hexStr);
415         return ret;
416     }
417 
418     ret = AddStringToJson(jsonObj, key, hexStr);
419     if (ret != CLIB_SUCCESS) {
420         ClibFree(hexStr);
421         return ret;
422     }
423 
424     ClibFree(hexStr);
425     return CLIB_SUCCESS;
426 }
427 
AddBoolToJson(CJson * jsonObj,const char * key,bool value)428 int32_t AddBoolToJson(CJson *jsonObj, const char *key, bool value)
429 {
430     if (jsonObj == NULL || key == NULL) {
431         return CLIB_ERR_NULL_PTR;
432     }
433 
434     cJSON *objInJson = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
435     if (objInJson == NULL) {
436         if (cJSON_AddBoolToObject(jsonObj, key, value) == NULL) {
437             return CLIB_ERR_JSON_GET;
438         }
439     } else {
440         cJSON *tmp = cJSON_CreateBool(value);
441         if (tmp == NULL) {
442             return CLIB_ERR_BAD_ALLOC;
443         }
444         if (cJSON_ReplaceItemInObjectCaseSensitive(jsonObj, key, tmp) == false) {
445             cJSON_Delete(tmp);
446             return CLIB_ERR_JSON_REPLACE;
447         }
448     }
449 
450     return CLIB_SUCCESS;
451 }
452 
AddIntToJson(CJson * jsonObj,const char * key,int value)453 int32_t AddIntToJson(CJson *jsonObj, const char *key, int value)
454 {
455     if (jsonObj == NULL || key == NULL) {
456         return CLIB_ERR_NULL_PTR;
457     }
458 
459     cJSON *objInJson = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
460     if (objInJson == NULL) {
461         if (cJSON_AddNumberToObject(jsonObj, key, value) == NULL) {
462             return CLIB_ERR_JSON_GET;
463         }
464     } else {
465         cJSON *tmp = cJSON_CreateNumber(value);
466         if (tmp == NULL) {
467             return CLIB_ERR_BAD_ALLOC;
468         }
469         if (cJSON_ReplaceItemInObjectCaseSensitive(jsonObj, key, tmp) == false) {
470             cJSON_Delete(tmp);
471             return CLIB_ERR_JSON_REPLACE;
472         }
473     }
474 
475     return CLIB_SUCCESS;
476 }
477 
AddInt64StringToJson(CJson * jsonObj,const char * key,int64_t value)478 int32_t AddInt64StringToJson(CJson *jsonObj, const char *key, int64_t value)
479 {
480     char buffer[65] = { 0 };
481     if (sprintf_s(buffer, sizeof(buffer), "%" PRId64, value) <= 0) {
482         return CLIB_FAILED;
483     }
484     if (AddStringToJson(jsonObj, key, buffer) != CLIB_SUCCESS) {
485         return CLIB_ERR_JSON_ADD;
486     }
487     return CLIB_SUCCESS;
488 }
489 
AddStringArrayToJson(CJson * jsonObj,const char * key,const char * const * stringArray,uint32_t arrayLen)490 int32_t AddStringArrayToJson(CJson *jsonObj, const char *key, const char * const *stringArray, uint32_t arrayLen)
491 {
492     if (jsonObj == NULL || key == NULL || stringArray == NULL) {
493         return CLIB_ERR_NULL_PTR;
494     }
495 
496     cJSON *strArrayObj = cJSON_CreateStringArray(stringArray, arrayLen);
497     if (strArrayObj == NULL) {
498         return CLIB_ERR_BAD_ALLOC;
499     }
500     if (cJSON_AddItemToObject(jsonObj, key, strArrayObj) == false) {
501         cJSON_Delete(strArrayObj);
502         return CLIB_ERR_JSON_ADD;
503     }
504     return CLIB_SUCCESS;
505 }
506 
ClearSensitiveStringInJson(CJson * jsonObj,const char * key)507 void ClearSensitiveStringInJson(CJson *jsonObj, const char *key)
508 {
509     if (jsonObj == NULL || key == NULL) {
510         return;
511     }
512     char *str = (char *)GetStringFromJson(jsonObj, key);
513     if (str == NULL) {
514         return;
515     }
516     (void)memset_s(str, strlen(str), 0, strlen(str));
517 }
518 
ClearAndFreeJsonString(char * jsonStr)519 void ClearAndFreeJsonString(char *jsonStr)
520 {
521     if (jsonStr == NULL) {
522         return;
523     }
524     (void)memset_s(jsonStr, strlen(jsonStr), 0, strlen(jsonStr));
525     FreeJsonString(jsonStr);
526 }
527