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