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