• 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 "hc_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     if (jsonStr != NULL) {
117         cJSON_free(jsonStr);
118     }
119 }
120 
GetItemNum(const CJson * jsonObj)121 int GetItemNum(const CJson *jsonObj)
122 {
123     if (jsonObj == NULL) {
124         return 0;
125     }
126     return cJSON_GetArraySize(jsonObj);
127 }
128 
GetItemKey(const CJson * item)129 const char *GetItemKey(const CJson *item)
130 {
131     if (item == NULL) {
132         return NULL;
133     }
134     return item->string;
135 }
136 
GetObjFromJson(const CJson * jsonObj,const char * key)137 CJson *GetObjFromJson(const CJson *jsonObj, const char *key)
138 {
139     if (jsonObj == NULL || key == NULL) {
140         return NULL;
141     }
142 
143     cJSON *objValue = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
144     if (objValue != NULL) {
145         return objValue;
146     }
147 
148     int len = cJSON_GetArraySize(jsonObj);
149     for (int i = 0; i < len; i++) {
150         cJSON *item = cJSON_GetArrayItem(jsonObj, i);
151         if (cJSON_IsObject(item)) {
152             cJSON *obj = GetObjFromJson(item, key);
153             if (obj != NULL) {
154                 return obj;
155             }
156         }
157     }
158 
159     return NULL;
160 }
161 
GetItemFromArray(const CJson * jsonArr,int index)162 CJson *GetItemFromArray(const CJson *jsonArr, int index)
163 {
164     if (jsonArr == NULL) {
165         return NULL;
166     }
167     return cJSON_GetArrayItem(jsonArr, index);
168 }
169 
GetStringFromJson(const CJson * jsonObj,const char * key)170 const char *GetStringFromJson(const CJson *jsonObj, const char *key)
171 {
172     if (jsonObj == NULL || key == NULL) {
173         return NULL;
174     }
175 
176     cJSON *jsonObjTmp = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
177     if (jsonObjTmp != NULL && cJSON_IsString(jsonObjTmp)) {
178         return cJSON_GetStringValue(jsonObjTmp);
179     }
180 
181     int len = cJSON_GetArraySize(jsonObj);
182     for (int i = 0; i < len; i++) {
183         cJSON *item = cJSON_GetArrayItem(jsonObj, i);
184         if (cJSON_IsObject(item)) {
185             const char *resValue = GetStringFromJson(item, key);
186             if (resValue != NULL) {
187                 return resValue;
188             }
189         }
190     }
191 
192     return NULL;
193 }
194 
GetByteLenFromJson(const CJson * jsonObj,const char * key,uint32_t * byteLen)195 int32_t GetByteLenFromJson(const CJson *jsonObj, const char *key, uint32_t *byteLen)
196 {
197     if (jsonObj == NULL || key == NULL || byteLen == NULL) {
198         return CLIB_ERR_NULL_PTR;
199     }
200 
201     const char *valueStr = GetStringFromJson(jsonObj, key);
202     if (valueStr == NULL) {
203         return CLIB_ERR_JSON_GET;
204     }
205     *byteLen = strlen(valueStr) / BYTE_TO_HEX_OPER_LENGTH;
206     return CLIB_SUCCESS;
207 }
208 
GetByteFromJson(const CJson * jsonObj,const char * key,uint8_t * byte,uint32_t len)209 int32_t GetByteFromJson(const CJson *jsonObj, const char *key, uint8_t *byte, uint32_t len)
210 {
211     if (jsonObj == NULL || key == NULL || byte == NULL) {
212         return CLIB_ERR_NULL_PTR;
213     }
214 
215     const char *valueStr = GetStringFromJson(jsonObj, key);
216     if (valueStr == NULL) {
217         return CLIB_ERR_JSON_GET;
218     }
219     if (len < strlen(valueStr) / BYTE_TO_HEX_OPER_LENGTH) {
220         return CLIB_ERR_INVALID_LEN;
221     }
222     return HexStringToByte(valueStr, byte, len);
223 }
224 
GetIntFromJson(const CJson * jsonObj,const char * key,int32_t * value)225 int32_t GetIntFromJson(const CJson *jsonObj, const char *key, int32_t *value)
226 {
227     if (jsonObj == NULL || key == NULL || value == NULL) {
228         return CLIB_ERR_NULL_PTR;
229     }
230 
231     cJSON *jsonObjTmp = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
232     if (jsonObjTmp != NULL && cJSON_IsNumber(jsonObjTmp)) {
233         *value = (int)cJSON_GetNumberValue(jsonObjTmp);
234         return CLIB_SUCCESS;
235     }
236 
237     int len = cJSON_GetArraySize(jsonObj);
238     for (int i = 0; i < len; i++) {
239         cJSON *item = cJSON_GetArrayItem(jsonObj, i);
240         if (cJSON_IsObject(item)) {
241             int32_t ret = GetIntFromJson(item, key, value);
242             if (ret == CLIB_SUCCESS) {
243                 return ret;
244             }
245         }
246     }
247 
248     return CLIB_ERR_JSON_GET;
249 }
250 
GetUnsignedIntFromJson(const CJson * jsonObj,const char * key,uint32_t * value)251 int32_t GetUnsignedIntFromJson(const CJson *jsonObj, const char *key, uint32_t *value)
252 {
253     if (jsonObj == NULL || key == NULL || value == NULL) {
254         return CLIB_ERR_NULL_PTR;
255     }
256 
257     cJSON *jsonObjTmp = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
258     if (jsonObjTmp != NULL && cJSON_IsNumber(jsonObjTmp)) {
259         double realValue = cJSON_GetNumberValue(jsonObjTmp);
260         if (realValue < 0) {
261             int32_t tmpValue = (int32_t)realValue;
262             *value = (uint32_t)tmpValue;
263         } else {
264             *value = (uint32_t)realValue;
265         }
266         return CLIB_SUCCESS;
267     }
268 
269     int len = cJSON_GetArraySize(jsonObj);
270     for (int i = 0; i < len; i++) {
271         cJSON *item = cJSON_GetArrayItem(jsonObj, i);
272         if (cJSON_IsObject(item)) {
273             int32_t ret = GetUnsignedIntFromJson(item, key, value);
274             if (ret == CLIB_SUCCESS) {
275                 return ret;
276             }
277         }
278     }
279 
280     return CLIB_ERR_JSON_GET;
281 }
282 
GetInt64FromJson(const CJson * jsonObj,const char * key,int64_t * value)283 int32_t GetInt64FromJson(const CJson *jsonObj, const char *key, int64_t *value)
284 {
285     const char *str = GetStringFromJson(jsonObj, key);
286     if (str == NULL) {
287         return CLIB_ERR_JSON_GET;
288     }
289     *value = StringToInt64(str);
290     return CLIB_SUCCESS;
291 }
292 
GetBoolFromJson(const CJson * jsonObj,const char * key,bool * value)293 int32_t GetBoolFromJson(const CJson *jsonObj, const char *key, bool *value)
294 {
295     if (jsonObj == NULL || key == NULL || value == NULL) {
296         return CLIB_ERR_NULL_PTR;
297     }
298 
299     cJSON *jsonObjTmp = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
300     if (jsonObjTmp != NULL && cJSON_IsBool(jsonObjTmp)) {
301         *value = cJSON_IsTrue(jsonObjTmp) ? true : false;
302         return CLIB_SUCCESS;
303     }
304 
305     int len = cJSON_GetArraySize(jsonObj);
306     for (int i = 0; i < len; i++) {
307         cJSON *item = cJSON_GetArrayItem(jsonObj, i);
308         if (cJSON_IsObject(item)) {
309             int32_t ret = GetBoolFromJson(item, key, value);
310             if (ret == CLIB_SUCCESS) {
311                 return ret;
312             }
313         }
314     }
315 
316     return CLIB_ERR_JSON_GET;
317 }
318 
GetStringValue(const CJson * item)319 char *GetStringValue(const CJson *item)
320 {
321     return cJSON_GetStringValue(item);
322 }
323 
AddObjToJson(CJson * jsonObj,const char * key,const CJson * childObj)324 int32_t AddObjToJson(CJson *jsonObj, const char *key, const CJson *childObj)
325 {
326     if (jsonObj == NULL || key == NULL || childObj == NULL) {
327         return CLIB_ERR_NULL_PTR;
328     }
329 
330     cJSON *tmpObj = cJSON_Duplicate(childObj, RECURSE_FLAG_TRUE);
331     if (tmpObj == NULL) {
332         return CLIB_ERR_JSON_DUPLICATE;
333     }
334 
335     cJSON *objInJson = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
336     if (objInJson == NULL) {
337         if (cJSON_AddItemToObject(jsonObj, key, tmpObj) == false) {
338             cJSON_Delete(tmpObj);
339             return CLIB_ERR_JSON_ADD;
340         }
341     } else {
342         if (cJSON_ReplaceItemInObjectCaseSensitive(jsonObj, key, tmpObj) == false) {
343             cJSON_Delete(tmpObj);
344             return CLIB_ERR_JSON_REPLACE;
345         }
346     }
347 
348     return CLIB_SUCCESS;
349 }
350 
AddObjToArray(CJson * jsonArr,CJson * item)351 int32_t AddObjToArray(CJson *jsonArr, CJson *item)
352 {
353     if (jsonArr == NULL || item == NULL) {
354         return CLIB_ERR_NULL_PTR;
355     }
356 
357     if (cJSON_IsArray(jsonArr) == false) {
358         return CLIB_ERR_INVALID_PARAM;
359     }
360 
361     bool ret = cJSON_AddItemToArray(jsonArr, item);
362     if (ret == false) {
363         return CLIB_ERR_JSON_ADD;
364     }
365 
366     return CLIB_SUCCESS;
367 }
368 
AddStringToArray(CJson * jsonArr,const char * string)369 int32_t AddStringToArray(CJson *jsonArr, const char *string)
370 {
371     if (jsonArr == NULL || string == NULL) {
372         return CLIB_ERR_NULL_PTR;
373     }
374 
375     if (cJSON_IsArray(jsonArr) == false) {
376         return CLIB_ERR_INVALID_PARAM;
377     }
378 
379     cJSON *strObj = cJSON_CreateString(string);
380     if (strObj == NULL) {
381         return CLIB_ERR_BAD_ALLOC;
382     }
383     bool ret = cJSON_AddItemToArray(jsonArr, strObj);
384     if (ret == false) {
385         cJSON_Delete(strObj);
386         return CLIB_ERR_JSON_ADD;
387     }
388 
389     return CLIB_SUCCESS;
390 }
391 
AddStringToJson(CJson * jsonObj,const char * key,const char * value)392 int32_t AddStringToJson(CJson *jsonObj, const char *key, const char *value)
393 {
394     if (jsonObj == NULL || key == NULL || value == NULL) {
395         return CLIB_ERR_NULL_PTR;
396     }
397 
398     cJSON *objInJson = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
399     if (objInJson == NULL) {
400         if (cJSON_AddStringToObject(jsonObj, key, value) == NULL) {
401             return CLIB_ERR_JSON_GET;
402         }
403     } else {
404         cJSON *tmp = cJSON_CreateString(value);
405         if (tmp == NULL) {
406             return CLIB_ERR_BAD_ALLOC;
407         }
408         if (cJSON_ReplaceItemInObjectCaseSensitive(jsonObj, key, tmp) == false) {
409             cJSON_Delete(tmp);
410             return CLIB_ERR_JSON_REPLACE;
411         }
412     }
413 
414     return CLIB_SUCCESS;
415 }
416 
AddByteToJson(CJson * jsonObj,const char * key,const uint8_t * byte,uint32_t len)417 int32_t AddByteToJson(CJson *jsonObj, const char *key, const uint8_t *byte, uint32_t len)
418 {
419     if (jsonObj == NULL || key == NULL || byte == NULL) {
420         return CLIB_ERR_NULL_PTR;
421     }
422 
423     uint32_t hexLen = len * BYTE_TO_HEX_OPER_LENGTH + 1;
424     char *hexStr = (char *)HcMalloc(hexLen, 0);
425     if (hexStr == NULL) {
426         return CLIB_ERR_BAD_ALLOC;
427     }
428     int32_t ret = ByteToHexString(byte, len, hexStr, hexLen);
429     if (ret != CLIB_SUCCESS) {
430         HcFree(hexStr);
431         return ret;
432     }
433 
434     ret = AddStringToJson(jsonObj, key, hexStr);
435     if (ret != CLIB_SUCCESS) {
436         HcFree(hexStr);
437         return ret;
438     }
439 
440     HcFree(hexStr);
441     return CLIB_SUCCESS;
442 }
443 
AddBoolToJson(CJson * jsonObj,const char * key,bool value)444 int32_t AddBoolToJson(CJson *jsonObj, const char *key, bool value)
445 {
446     if (jsonObj == NULL || key == NULL) {
447         return CLIB_ERR_NULL_PTR;
448     }
449 
450     cJSON *objInJson = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
451     if (objInJson == NULL) {
452         if (cJSON_AddBoolToObject(jsonObj, key, value) == NULL) {
453             return CLIB_ERR_JSON_GET;
454         }
455     } else {
456         cJSON *tmp = cJSON_CreateBool(value);
457         if (tmp == NULL) {
458             return CLIB_ERR_BAD_ALLOC;
459         }
460         if (cJSON_ReplaceItemInObjectCaseSensitive(jsonObj, key, tmp) == false) {
461             cJSON_Delete(tmp);
462             return CLIB_ERR_JSON_REPLACE;
463         }
464     }
465 
466     return CLIB_SUCCESS;
467 }
468 
AddIntToJson(CJson * jsonObj,const char * key,int value)469 int32_t AddIntToJson(CJson *jsonObj, const char *key, int value)
470 {
471     if (jsonObj == NULL || key == NULL) {
472         return CLIB_ERR_NULL_PTR;
473     }
474 
475     cJSON *objInJson = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
476     if (objInJson == NULL) {
477         if (cJSON_AddNumberToObject(jsonObj, key, value) == NULL) {
478             return CLIB_ERR_JSON_GET;
479         }
480     } else {
481         cJSON *tmp = cJSON_CreateNumber(value);
482         if (tmp == NULL) {
483             return CLIB_ERR_BAD_ALLOC;
484         }
485         if (cJSON_ReplaceItemInObjectCaseSensitive(jsonObj, key, tmp) == false) {
486             cJSON_Delete(tmp);
487             return CLIB_ERR_JSON_REPLACE;
488         }
489     }
490 
491     return CLIB_SUCCESS;
492 }
493 
AddInt64StringToJson(CJson * jsonObj,const char * key,int64_t value)494 int32_t AddInt64StringToJson(CJson *jsonObj, const char *key, int64_t value)
495 {
496     char buffer[65] = { 0 };
497     if (sprintf_s(buffer, sizeof(buffer), "%" PRId64, value) <= 0) {
498         return CLIB_FAILED;
499     }
500     if (AddStringToJson(jsonObj, key, buffer) != CLIB_SUCCESS) {
501         return CLIB_ERR_JSON_ADD;
502     }
503     return CLIB_SUCCESS;
504 }
505 
AddStringArrayToJson(CJson * jsonObj,const char * key,const char * const * stringArray,uint32_t arrayLen)506 int32_t AddStringArrayToJson(CJson *jsonObj, const char *key, const char * const *stringArray, uint32_t arrayLen)
507 {
508     if (jsonObj == NULL || key == NULL || stringArray == NULL) {
509         return CLIB_ERR_NULL_PTR;
510     }
511 
512     cJSON *strArrayObj = cJSON_CreateStringArray(stringArray, arrayLen);
513     if (strArrayObj == NULL) {
514         return CLIB_ERR_BAD_ALLOC;
515     }
516     if (cJSON_AddItemToObject(jsonObj, key, strArrayObj) == false) {
517         cJSON_Delete(strArrayObj);
518         return CLIB_ERR_JSON_ADD;
519     }
520     return CLIB_SUCCESS;
521 }
522 
ClearSensitiveStringInJson(CJson * jsonObj,const char * key)523 void ClearSensitiveStringInJson(CJson *jsonObj, const char *key)
524 {
525     if (jsonObj == NULL || key == NULL) {
526         return;
527     }
528     char *str = (char *)GetStringFromJson(jsonObj, key);
529     if (str == NULL) {
530         return;
531     }
532     (void)memset_s(str, strlen(str), 0, strlen(str));
533 }
534 
ClearAndFreeJsonString(char * jsonStr)535 void ClearAndFreeJsonString(char *jsonStr)
536 {
537     if (jsonStr == NULL) {
538         return;
539     }
540     (void)memset_s(jsonStr, strlen(jsonStr), 0, strlen(jsonStr));
541     FreeJsonString(jsonStr);
542 }
543