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_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 (strcmp(key, curItem->string) != 0) {
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
GetInt64FromJson(const CJson * jsonObj,const char * key,int64_t * value)341 int32_t GetInt64FromJson(const CJson *jsonObj, const char *key, int64_t *value)
342 {
343 const char *str = GetStringFromJson(jsonObj, key);
344 if (str == NULL) {
345 return CLIB_ERR_JSON_GET;
346 }
347 *value = StringToInt64(str);
348 return CLIB_SUCCESS;
349 }
350
GetBoolFromJson(const CJson * jsonObj,const char * key,bool * value)351 int32_t GetBoolFromJson(const CJson *jsonObj, const char *key, bool *value)
352 {
353 if (jsonObj == NULL || key == NULL || value == NULL) {
354 return CLIB_ERR_NULL_PTR;
355 }
356
357 cJSON *jsonObjTmp = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
358 if (jsonObjTmp != NULL && cJSON_IsBool(jsonObjTmp)) {
359 *value = cJSON_IsTrue(jsonObjTmp) ? true : false;
360 return CLIB_SUCCESS;
361 }
362
363 int len = cJSON_GetArraySize(jsonObj);
364 for (int i = 0; i < len; i++) {
365 cJSON *item = cJSON_GetArrayItem(jsonObj, i);
366 if (cJSON_IsObject(item)) {
367 int32_t ret = GetBoolFromJson(item, key, value);
368 if (ret == CLIB_SUCCESS) {
369 return ret;
370 }
371 }
372 }
373
374 return CLIB_ERR_JSON_GET;
375 }
376
GetStringValue(const CJson * item)377 char *GetStringValue(const CJson *item)
378 {
379 return cJSON_GetStringValue(item);
380 }
381
AddObjToJson(CJson * jsonObj,const char * key,const CJson * childObj)382 int32_t AddObjToJson(CJson *jsonObj, const char *key, const CJson *childObj)
383 {
384 if (jsonObj == NULL || key == NULL || childObj == NULL) {
385 return CLIB_ERR_NULL_PTR;
386 }
387
388 cJSON *tmpObj = cJSON_Duplicate(childObj, RECURSE_FLAG_TRUE);
389 if (tmpObj == NULL) {
390 return CLIB_ERR_JSON_DUPLICATE;
391 }
392
393 cJSON *objInJson = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
394 if (objInJson == NULL) {
395 if (cJSON_AddItemToObject(jsonObj, key, tmpObj) == false) {
396 cJSON_Delete(tmpObj);
397 return CLIB_ERR_JSON_ADD;
398 }
399 } else {
400 if (cJSON_ReplaceItemInObjectCaseSensitive(jsonObj, key, tmpObj) == false) {
401 cJSON_Delete(tmpObj);
402 return CLIB_ERR_JSON_REPLACE;
403 }
404 }
405
406 return CLIB_SUCCESS;
407 }
408
AddObjToArray(CJson * jsonArr,CJson * item)409 int32_t AddObjToArray(CJson *jsonArr, CJson *item)
410 {
411 if (jsonArr == NULL || item == NULL) {
412 return CLIB_ERR_NULL_PTR;
413 }
414
415 if (cJSON_IsArray(jsonArr) == false) {
416 return CLIB_ERR_INVALID_PARAM;
417 }
418
419 bool ret = cJSON_AddItemToArray(jsonArr, item);
420 if (ret == false) {
421 return CLIB_ERR_JSON_ADD;
422 }
423
424 return CLIB_SUCCESS;
425 }
426
AddStringToArray(CJson * jsonArr,const char * string)427 int32_t AddStringToArray(CJson *jsonArr, const char *string)
428 {
429 if (jsonArr == NULL || string == NULL) {
430 return CLIB_ERR_NULL_PTR;
431 }
432
433 if (cJSON_IsArray(jsonArr) == false) {
434 return CLIB_ERR_INVALID_PARAM;
435 }
436
437 cJSON *strObj = cJSON_CreateString(string);
438 if (strObj == NULL) {
439 return CLIB_ERR_BAD_ALLOC;
440 }
441 bool ret = cJSON_AddItemToArray(jsonArr, strObj);
442 if (ret == false) {
443 cJSON_Delete(strObj);
444 return CLIB_ERR_JSON_ADD;
445 }
446
447 return CLIB_SUCCESS;
448 }
449
AddStringToJson(CJson * jsonObj,const char * key,const char * value)450 int32_t AddStringToJson(CJson *jsonObj, const char *key, const char *value)
451 {
452 if (jsonObj == NULL || key == NULL || value == NULL) {
453 return CLIB_ERR_NULL_PTR;
454 }
455
456 cJSON *objInJson = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
457 if (objInJson == NULL) {
458 if (cJSON_AddStringToObject(jsonObj, key, value) == NULL) {
459 return CLIB_ERR_JSON_GET;
460 }
461 } else {
462 cJSON *tmp = cJSON_CreateString(value);
463 if (tmp == NULL) {
464 return CLIB_ERR_BAD_ALLOC;
465 }
466 if (cJSON_ReplaceItemInObjectCaseSensitive(jsonObj, key, tmp) == false) {
467 cJSON_Delete(tmp);
468 return CLIB_ERR_JSON_REPLACE;
469 }
470 }
471
472 return CLIB_SUCCESS;
473 }
474
AddByteToJson(CJson * jsonObj,const char * key,const uint8_t * byte,uint32_t len)475 int32_t AddByteToJson(CJson *jsonObj, const char *key, const uint8_t *byte, uint32_t len)
476 {
477 if (jsonObj == NULL || key == NULL || byte == NULL) {
478 return CLIB_ERR_NULL_PTR;
479 }
480
481 uint32_t hexLen = len * BYTE_TO_HEX_OPER_LENGTH + 1;
482 char *hexStr = (char *)HcMalloc(hexLen, 0);
483 if (hexStr == NULL) {
484 return CLIB_ERR_BAD_ALLOC;
485 }
486 int32_t ret = ByteToHexString(byte, len, hexStr, hexLen);
487 if (ret != CLIB_SUCCESS) {
488 HcFree(hexStr);
489 return ret;
490 }
491
492 ret = AddStringToJson(jsonObj, key, hexStr);
493 if (ret != CLIB_SUCCESS) {
494 HcFree(hexStr);
495 return ret;
496 }
497
498 HcFree(hexStr);
499 return CLIB_SUCCESS;
500 }
501
AddBoolToJson(CJson * jsonObj,const char * key,bool value)502 int32_t AddBoolToJson(CJson *jsonObj, const char *key, bool value)
503 {
504 if (jsonObj == NULL || key == NULL) {
505 return CLIB_ERR_NULL_PTR;
506 }
507
508 cJSON *objInJson = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
509 if (objInJson == NULL) {
510 if (cJSON_AddBoolToObject(jsonObj, key, value) == NULL) {
511 return CLIB_ERR_JSON_GET;
512 }
513 } else {
514 cJSON *tmp = cJSON_CreateBool(value);
515 if (tmp == NULL) {
516 return CLIB_ERR_BAD_ALLOC;
517 }
518 if (cJSON_ReplaceItemInObjectCaseSensitive(jsonObj, key, tmp) == false) {
519 cJSON_Delete(tmp);
520 return CLIB_ERR_JSON_REPLACE;
521 }
522 }
523
524 return CLIB_SUCCESS;
525 }
526
AddIntToJson(CJson * jsonObj,const char * key,int value)527 int32_t AddIntToJson(CJson *jsonObj, const char *key, int value)
528 {
529 if (jsonObj == NULL || key == NULL) {
530 return CLIB_ERR_NULL_PTR;
531 }
532
533 cJSON *objInJson = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
534 if (objInJson == NULL) {
535 if (cJSON_AddNumberToObject(jsonObj, key, value) == NULL) {
536 return CLIB_ERR_JSON_GET;
537 }
538 } else {
539 cJSON *tmp = cJSON_CreateNumber(value);
540 if (tmp == NULL) {
541 return CLIB_ERR_BAD_ALLOC;
542 }
543 if (cJSON_ReplaceItemInObjectCaseSensitive(jsonObj, key, tmp) == false) {
544 cJSON_Delete(tmp);
545 return CLIB_ERR_JSON_REPLACE;
546 }
547 }
548
549 return CLIB_SUCCESS;
550 }
551
AddInt64StringToJson(CJson * jsonObj,const char * key,int64_t value)552 int32_t AddInt64StringToJson(CJson *jsonObj, const char *key, int64_t value)
553 {
554 char buffer[65] = { 0 };
555 if (sprintf_s(buffer, sizeof(buffer), "%" PRId64, value) <= 0) {
556 return CLIB_FAILED;
557 }
558 if (AddStringToJson(jsonObj, key, buffer) != CLIB_SUCCESS) {
559 return CLIB_ERR_JSON_ADD;
560 }
561 return CLIB_SUCCESS;
562 }
563
AddStringArrayToJson(CJson * jsonObj,const char * key,const char * const * stringArray,uint32_t arrayLen)564 int32_t AddStringArrayToJson(CJson *jsonObj, const char *key, const char * const *stringArray, uint32_t arrayLen)
565 {
566 if (jsonObj == NULL || key == NULL || stringArray == NULL) {
567 return CLIB_ERR_NULL_PTR;
568 }
569
570 cJSON *strArrayObj = cJSON_CreateStringArray(stringArray, arrayLen);
571 if (strArrayObj == NULL) {
572 return CLIB_ERR_BAD_ALLOC;
573 }
574 if (cJSON_AddItemToObject(jsonObj, key, strArrayObj) == false) {
575 cJSON_Delete(strArrayObj);
576 return CLIB_ERR_JSON_ADD;
577 }
578 return CLIB_SUCCESS;
579 }
580
ClearSensitiveStringInJson(CJson * jsonObj,const char * key)581 void ClearSensitiveStringInJson(CJson *jsonObj, const char *key)
582 {
583 if (jsonObj == NULL || key == NULL) {
584 return;
585 }
586 char *str = (char *)GetStringFromJson(jsonObj, key);
587 if (str == NULL) {
588 return;
589 }
590 (void)memset_s(str, strlen(str), 0, strlen(str));
591 }
592
ClearAndFreeJsonString(char * jsonStr)593 void ClearAndFreeJsonString(char *jsonStr)
594 {
595 if (jsonStr == NULL) {
596 return;
597 }
598 (void)memset_s(jsonStr, strlen(jsonStr), 0, strlen(jsonStr));
599 FreeJsonString(jsonStr);
600 }
601