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