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