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 "clib_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 cJSON_free(jsonStr);
117 }
118
GetItemNum(const CJson * jsonObj)119 int GetItemNum(const CJson *jsonObj)
120 {
121 if (jsonObj == NULL) {
122 return 0;
123 }
124 return cJSON_GetArraySize(jsonObj);
125 }
126
GetItemKey(const CJson * item)127 const char *GetItemKey(const CJson *item)
128 {
129 if (item == NULL) {
130 return NULL;
131 }
132 return item->string;
133 }
134
GetObjFromJson(const CJson * jsonObj,const char * key)135 CJson *GetObjFromJson(const CJson *jsonObj, const char *key)
136 {
137 if (jsonObj == NULL || key == NULL) {
138 return NULL;
139 }
140
141 cJSON *objValue = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
142 if (objValue != NULL) {
143 return objValue;
144 }
145
146 int len = cJSON_GetArraySize(jsonObj);
147 for (int i = 0; i < len; i++) {
148 cJSON *item = cJSON_GetArrayItem(jsonObj, i);
149 if (cJSON_IsObject(item)) {
150 cJSON *obj = GetObjFromJson(item, key);
151 if (obj != NULL) {
152 return obj;
153 }
154 }
155 }
156
157 return NULL;
158 }
159
GetItemFromArray(const CJson * jsonArr,int index)160 CJson *GetItemFromArray(const CJson *jsonArr, int index)
161 {
162 if (jsonArr == NULL) {
163 return NULL;
164 }
165 return cJSON_GetArrayItem(jsonArr, index);
166 }
167
GetStringFromJson(const CJson * jsonObj,const char * key)168 const char *GetStringFromJson(const CJson *jsonObj, const char *key)
169 {
170 if (jsonObj == NULL || key == NULL) {
171 return NULL;
172 }
173
174 cJSON *jsonObjTmp = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
175 if (jsonObjTmp != NULL && cJSON_IsString(jsonObjTmp)) {
176 return cJSON_GetStringValue(jsonObjTmp);
177 }
178
179 int len = cJSON_GetArraySize(jsonObj);
180 for (int i = 0; i < len; i++) {
181 cJSON *item = cJSON_GetArrayItem(jsonObj, i);
182 if (cJSON_IsObject(item)) {
183 const char *resValue = GetStringFromJson(item, key);
184 if (resValue != NULL) {
185 return resValue;
186 }
187 }
188 }
189
190 return NULL;
191 }
192
GetByteFromJson(const CJson * jsonObj,const char * key,uint8_t * byte,uint32_t len)193 int32_t GetByteFromJson(const CJson *jsonObj, const char *key, uint8_t *byte, uint32_t len)
194 {
195 if (jsonObj == NULL || key == NULL || byte == NULL) {
196 return CLIB_ERR_NULL_PTR;
197 }
198
199 const char *valueStr = GetStringFromJson(jsonObj, key);
200 if (valueStr == NULL) {
201 return CLIB_ERR_JSON_GET;
202 }
203 if (len < strlen(valueStr) / BYTE_TO_HEX_OPER_LENGTH) {
204 return CLIB_ERR_INVALID_LEN;
205 }
206 return HexStringToByte(valueStr, byte, len);
207 }
208
GetIntFromJson(const CJson * jsonObj,const char * key,int32_t * value)209 int32_t GetIntFromJson(const CJson *jsonObj, const char *key, int32_t *value)
210 {
211 if (jsonObj == NULL || key == NULL || value == NULL) {
212 return CLIB_ERR_NULL_PTR;
213 }
214
215 cJSON *jsonObjTmp = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
216 if (jsonObjTmp != NULL && cJSON_IsNumber(jsonObjTmp)) {
217 *value = (int)cJSON_GetNumberValue(jsonObjTmp);
218 return CLIB_SUCCESS;
219 }
220
221 int len = cJSON_GetArraySize(jsonObj);
222 for (int i = 0; i < len; i++) {
223 cJSON *item = cJSON_GetArrayItem(jsonObj, i);
224 if (cJSON_IsObject(item)) {
225 int32_t ret = GetIntFromJson(item, key, value);
226 if (ret == CLIB_SUCCESS) {
227 return ret;
228 }
229 }
230 }
231
232 return CLIB_ERR_JSON_GET;
233 }
234
GetUnsignedIntFromJson(const CJson * jsonObj,const char * key,uint32_t * value)235 int32_t GetUnsignedIntFromJson(const CJson *jsonObj, const char *key, uint32_t *value)
236 {
237 if (jsonObj == NULL || key == NULL || value == NULL) {
238 return CLIB_ERR_NULL_PTR;
239 }
240
241 cJSON *jsonObjTmp = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
242 if (jsonObjTmp != NULL && cJSON_IsNumber(jsonObjTmp)) {
243 double realValue = cJSON_GetNumberValue(jsonObjTmp);
244 if (realValue < 0) {
245 int32_t tmpValue = (int32_t)realValue;
246 *value = (uint32_t)tmpValue;
247 } else {
248 *value = (uint32_t)realValue;
249 }
250 return CLIB_SUCCESS;
251 }
252
253 int len = cJSON_GetArraySize(jsonObj);
254 for (int i = 0; i < len; i++) {
255 cJSON *item = cJSON_GetArrayItem(jsonObj, i);
256 if (cJSON_IsObject(item)) {
257 int32_t ret = GetUnsignedIntFromJson(item, key, value);
258 if (ret == CLIB_SUCCESS) {
259 return ret;
260 }
261 }
262 }
263
264 return CLIB_ERR_JSON_GET;
265 }
266
GetInt64FromJson(const CJson * jsonObj,const char * key,int64_t * value)267 int32_t GetInt64FromJson(const CJson *jsonObj, const char *key, int64_t *value)
268 {
269 const char *str = GetStringFromJson(jsonObj, key);
270 if (str == NULL) {
271 return CLIB_ERR_JSON_GET;
272 }
273 *value = StringToInt64(str);
274 return CLIB_SUCCESS;
275 }
276
GetBoolFromJson(const CJson * jsonObj,const char * key,bool * value)277 int32_t GetBoolFromJson(const CJson *jsonObj, const char *key, bool *value)
278 {
279 if (jsonObj == NULL || key == NULL || value == NULL) {
280 return CLIB_ERR_NULL_PTR;
281 }
282
283 cJSON *jsonObjTmp = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
284 if (jsonObjTmp != NULL && cJSON_IsBool(jsonObjTmp)) {
285 *value = cJSON_IsTrue(jsonObjTmp) ? true : false;
286 return CLIB_SUCCESS;
287 }
288
289 int len = cJSON_GetArraySize(jsonObj);
290 for (int i = 0; i < len; i++) {
291 cJSON *item = cJSON_GetArrayItem(jsonObj, i);
292 if (cJSON_IsObject(item)) {
293 int32_t ret = GetBoolFromJson(item, key, value);
294 if (ret == CLIB_SUCCESS) {
295 return ret;
296 }
297 }
298 }
299
300 return CLIB_ERR_JSON_GET;
301 }
302
GetStringValue(const CJson * item)303 char *GetStringValue(const CJson *item)
304 {
305 return cJSON_GetStringValue(item);
306 }
307
AddObjToJson(CJson * jsonObj,const char * key,const CJson * childObj)308 int32_t AddObjToJson(CJson *jsonObj, const char *key, const CJson *childObj)
309 {
310 if (jsonObj == NULL || key == NULL || childObj == NULL) {
311 return CLIB_ERR_NULL_PTR;
312 }
313
314 cJSON *tmpObj = cJSON_Duplicate(childObj, RECURSE_FLAG_TRUE);
315 if (tmpObj == NULL) {
316 return CLIB_ERR_JSON_DUPLICATE;
317 }
318
319 cJSON *objInJson = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
320 if (objInJson == NULL) {
321 if (cJSON_AddItemToObject(jsonObj, key, tmpObj) == false) {
322 cJSON_Delete(tmpObj);
323 return CLIB_ERR_JSON_ADD;
324 }
325 } else {
326 if (cJSON_ReplaceItemInObjectCaseSensitive(jsonObj, key, tmpObj) == false) {
327 cJSON_Delete(tmpObj);
328 return CLIB_ERR_JSON_REPLACE;
329 }
330 }
331
332 return CLIB_SUCCESS;
333 }
334
AddObjToArray(CJson * jsonArr,CJson * item)335 int32_t AddObjToArray(CJson *jsonArr, CJson *item)
336 {
337 if (jsonArr == NULL || item == NULL) {
338 return CLIB_ERR_NULL_PTR;
339 }
340
341 if (cJSON_IsArray(jsonArr) == false) {
342 return CLIB_ERR_INVALID_PARAM;
343 }
344
345 bool ret = cJSON_AddItemToArray(jsonArr, item);
346 if (ret == false) {
347 return CLIB_ERR_JSON_ADD;
348 }
349
350 return CLIB_SUCCESS;
351 }
352
AddStringToArray(CJson * jsonArr,const char * string)353 int32_t AddStringToArray(CJson *jsonArr, const char *string)
354 {
355 if (jsonArr == NULL || string == NULL) {
356 return CLIB_ERR_NULL_PTR;
357 }
358
359 if (cJSON_IsArray(jsonArr) == false) {
360 return CLIB_ERR_INVALID_PARAM;
361 }
362
363 cJSON *strObj = cJSON_CreateString(string);
364 if (strObj == NULL) {
365 return CLIB_ERR_BAD_ALLOC;
366 }
367 bool ret = cJSON_AddItemToArray(jsonArr, strObj);
368 if (ret == false) {
369 cJSON_Delete(strObj);
370 return CLIB_ERR_JSON_ADD;
371 }
372
373 return CLIB_SUCCESS;
374 }
375
AddStringToJson(CJson * jsonObj,const char * key,const char * value)376 int32_t AddStringToJson(CJson *jsonObj, const char *key, const char *value)
377 {
378 if (jsonObj == NULL || key == NULL || value == NULL) {
379 return CLIB_ERR_NULL_PTR;
380 }
381
382 cJSON *objInJson = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
383 if (objInJson == NULL) {
384 if (cJSON_AddStringToObject(jsonObj, key, value) == NULL) {
385 return CLIB_ERR_JSON_GET;
386 }
387 } else {
388 cJSON *tmp = cJSON_CreateString(value);
389 if (tmp == NULL) {
390 return CLIB_ERR_BAD_ALLOC;
391 }
392 if (cJSON_ReplaceItemInObjectCaseSensitive(jsonObj, key, tmp) == false) {
393 cJSON_Delete(tmp);
394 return CLIB_ERR_JSON_REPLACE;
395 }
396 }
397
398 return CLIB_SUCCESS;
399 }
400
AddByteToJson(CJson * jsonObj,const char * key,const uint8_t * byte,uint32_t len)401 int32_t AddByteToJson(CJson *jsonObj, const char *key, const uint8_t *byte, uint32_t len)
402 {
403 if (jsonObj == NULL || key == NULL || byte == NULL) {
404 return CLIB_ERR_NULL_PTR;
405 }
406
407 uint32_t hexLen = len * BYTE_TO_HEX_OPER_LENGTH + 1;
408 char *hexStr = (char *)ClibMalloc(hexLen, 0);
409 if (hexStr == NULL) {
410 return CLIB_ERR_BAD_ALLOC;
411 }
412 int32_t ret = ByteToHexString(byte, len, hexStr, hexLen);
413 if (ret != CLIB_SUCCESS) {
414 ClibFree(hexStr);
415 return ret;
416 }
417
418 ret = AddStringToJson(jsonObj, key, hexStr);
419 if (ret != CLIB_SUCCESS) {
420 ClibFree(hexStr);
421 return ret;
422 }
423
424 ClibFree(hexStr);
425 return CLIB_SUCCESS;
426 }
427
AddBoolToJson(CJson * jsonObj,const char * key,bool value)428 int32_t AddBoolToJson(CJson *jsonObj, const char *key, bool value)
429 {
430 if (jsonObj == NULL || key == NULL) {
431 return CLIB_ERR_NULL_PTR;
432 }
433
434 cJSON *objInJson = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
435 if (objInJson == NULL) {
436 if (cJSON_AddBoolToObject(jsonObj, key, value) == NULL) {
437 return CLIB_ERR_JSON_GET;
438 }
439 } else {
440 cJSON *tmp = cJSON_CreateBool(value);
441 if (tmp == NULL) {
442 return CLIB_ERR_BAD_ALLOC;
443 }
444 if (cJSON_ReplaceItemInObjectCaseSensitive(jsonObj, key, tmp) == false) {
445 cJSON_Delete(tmp);
446 return CLIB_ERR_JSON_REPLACE;
447 }
448 }
449
450 return CLIB_SUCCESS;
451 }
452
AddIntToJson(CJson * jsonObj,const char * key,int value)453 int32_t AddIntToJson(CJson *jsonObj, const char *key, int value)
454 {
455 if (jsonObj == NULL || key == NULL) {
456 return CLIB_ERR_NULL_PTR;
457 }
458
459 cJSON *objInJson = cJSON_GetObjectItemCaseSensitive(jsonObj, key);
460 if (objInJson == NULL) {
461 if (cJSON_AddNumberToObject(jsonObj, key, value) == NULL) {
462 return CLIB_ERR_JSON_GET;
463 }
464 } else {
465 cJSON *tmp = cJSON_CreateNumber(value);
466 if (tmp == NULL) {
467 return CLIB_ERR_BAD_ALLOC;
468 }
469 if (cJSON_ReplaceItemInObjectCaseSensitive(jsonObj, key, tmp) == false) {
470 cJSON_Delete(tmp);
471 return CLIB_ERR_JSON_REPLACE;
472 }
473 }
474
475 return CLIB_SUCCESS;
476 }
477
AddInt64StringToJson(CJson * jsonObj,const char * key,int64_t value)478 int32_t AddInt64StringToJson(CJson *jsonObj, const char *key, int64_t value)
479 {
480 char buffer[65] = { 0 };
481 if (sprintf_s(buffer, sizeof(buffer), "%" PRId64, value) <= 0) {
482 return CLIB_FAILED;
483 }
484 if (AddStringToJson(jsonObj, key, buffer) != CLIB_SUCCESS) {
485 return CLIB_ERR_JSON_ADD;
486 }
487 return CLIB_SUCCESS;
488 }
489
AddStringArrayToJson(CJson * jsonObj,const char * key,const char * const * stringArray,uint32_t arrayLen)490 int32_t AddStringArrayToJson(CJson *jsonObj, const char *key, const char * const *stringArray, uint32_t arrayLen)
491 {
492 if (jsonObj == NULL || key == NULL || stringArray == NULL) {
493 return CLIB_ERR_NULL_PTR;
494 }
495
496 cJSON *strArrayObj = cJSON_CreateStringArray(stringArray, arrayLen);
497 if (strArrayObj == NULL) {
498 return CLIB_ERR_BAD_ALLOC;
499 }
500 if (cJSON_AddItemToObject(jsonObj, key, strArrayObj) == false) {
501 cJSON_Delete(strArrayObj);
502 return CLIB_ERR_JSON_ADD;
503 }
504 return CLIB_SUCCESS;
505 }
506
ClearSensitiveStringInJson(CJson * jsonObj,const char * key)507 void ClearSensitiveStringInJson(CJson *jsonObj, const char *key)
508 {
509 if (jsonObj == NULL || key == NULL) {
510 return;
511 }
512 char *str = (char *)GetStringFromJson(jsonObj, key);
513 if (str == NULL) {
514 return;
515 }
516 (void)memset_s(str, strlen(str), 0, strlen(str));
517 }
518
ClearAndFreeJsonString(char * jsonStr)519 void ClearAndFreeJsonString(char *jsonStr)
520 {
521 if (jsonStr == NULL) {
522 return;
523 }
524 (void)memset_s(jsonStr, strlen(jsonStr), 0, strlen(jsonStr));
525 FreeJsonString(jsonStr);
526 }
527