From cf7d1953c9bd80dbc7642459dfedf13c23ec0f23 Mon Sep 17 00:00:00 2001 From: sunchb <448573057@qq.com> Date: Tue, 25 Feb 2020 17:38:54 +0800 Subject: [PATCH] fix the array size. --- demo/test2.c | 46 +++++++++--------- inc/cson_reflect.h | 3 +- inc/cson_util.h | 23 +++++++++ src/cson_packer.c | 29 +++++++----- src/cson_parser.c | 115 +++++++++++++-------------------------------- src/cson_reflect.c | 20 ++++++-- src/cson_util.c | 107 +++++++++++++++++++++++++++++++++++++++++ 7 files changed, 219 insertions(+), 124 deletions(-) create mode 100644 inc/cson_util.h create mode 100644 src/cson_util.c diff --git a/demo/test2.c b/demo/test2.c index f06e679..78c1782 100644 --- a/demo/test2.c +++ b/demo/test2.c @@ -5,36 +5,36 @@ typedef struct { char* name; char* jump_url; -}ClassInfoChild; +} ClassInfoChild; typedef struct { - int has_child; - char* icon; - int id; - char* name; - size_t childrenNum; + int has_child; + char* icon; + int id; + char* name; + char childrenNum; ClassInfoChild* children; -}ClassInfo; +} ClassInfo; typedef struct { - long long timestamp; - size_t infoNum; - ClassInfo* info; -}Data; + long long timestamp; + size_t infoNum; + ClassInfo* info; +} Data; typedef struct { - int status; - Data data; - int errcode; -}Response; + int status; + Data data; + int errcode; +} Response; -reflect_item_t ClassInfoChildTbl[] = { +reflect_item_t ClassInfoChildTbl[] = { _property_string(ClassInfoChild, name), _property_string(ClassInfoChild, jump_url), _property_end() }; -reflect_item_t ClassInfoTbl[] = { +reflect_item_t ClassInfoTbl[] = { _property_int(ClassInfo, has_child), _property_string(ClassInfo, icon), _property_int(ClassInfo, id), @@ -44,16 +44,16 @@ reflect_item_t ClassInfoTbl[] = { _property_end() }; -reflect_item_t DataTbl[] = { +reflect_item_t DataTbl[] = { _property_int(Data, timestamp), _property_int(Data, infoNum), _property_array_object(Data, info, ClassInfoTbl, ClassInfo, infoNum), _property_end() }; -reflect_item_t ResponseTbl[] = { +reflect_item_t ResponseTbl[] = { _property_int(Response, status), - _property_obj(Response, data, DataTbl), + _property_obj(Response, data, DataTbl), _property_int(Response, errcode), _property_end() }; @@ -97,9 +97,9 @@ static void freePlayList(Response* list) csonLoopProperty(list, ResponseTbl, freePointer); } - -void test2(){ - printf("=========================================\n"); +void test2() +{ + printf("=========================================\n"); printf("\t\tRunning %s\n", __FUNCTION__); printf("=========================================\n"); Response resp; diff --git a/inc/cson_reflect.h b/inc/cson_reflect.h index 40065e0..c5b06c7 100644 --- a/inc/cson_reflect.h +++ b/inc/cson_reflect.h @@ -119,10 +119,11 @@ extern const reflect_item_t realReflectTbl[]; * @param obj: object to be operated. * @param field: * @param tbl: property table of the type. + * @param pIndex: return index of the field in tbl. * * @return address of field. */ -void* csonGetProperty(void* obj, const char* field, const reflect_item_t* tbl); +void* csonGetProperty(void* obj, const char* field, const reflect_item_t* tbl, int* pIndex); /** * @brief set the field of object to specified data. diff --git a/inc/cson_util.h b/inc/cson_util.h new file mode 100644 index 0000000..f1c9865 --- /dev/null +++ b/inc/cson_util.h @@ -0,0 +1,23 @@ + +#ifndef _UTIL_H_ +#define _UTIL_H_ + +#include "cson.h" + +typedef union { + char c; + short s; + int i; + long long l; +}integer_val_t; + +typedef struct { + integer_val_t val; + int size; +}integer_t; + +int getIntegerValue(cson_t jo_tmp, int size, integer_val_t* i); +int checkIntegerValue(long long val, int size, integer_val_t* i); +long long getIntegerValueFromPointer(void* ptr, int size); + +#endif \ No newline at end of file diff --git a/src/cson_packer.c b/src/cson_packer.c index a16adb4..ff80257 100644 --- a/src/cson_packer.c +++ b/src/cson_packer.c @@ -3,6 +3,7 @@ * @author sun_chb@126.com */ #include "cson.h" +#include "cson_util.h" #include "stdio.h" #include "stdlib.h" @@ -92,15 +93,9 @@ int getJsonInteger(void* input, const reflect_item_t* tbl, int index, cson_t* ob void* pSrc = (void*)((char*)input + tbl[index].offset); - if(tbl[index].size == sizeof(char)){ - *obj = cson_integer(*((char*)pSrc)); - }else if(tbl[index].size == sizeof(short)){ - *obj = cson_integer(*((short*)pSrc)); - }else if(tbl[index].size == sizeof(int)){ - *obj = cson_integer(*((int*)pSrc)); - }else{ - *obj = cson_integer(*((long long*)pSrc)); - } + long long val = getIntegerValueFromPointer(pSrc, tbl[index].size); + + *obj = cson_integer(val); return ERR_NONE; } @@ -133,17 +128,23 @@ int getJsonObject(void* input, const reflect_item_t* tbl, int index, cson_t* obj int getJsonArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj) { int ret = ERR_NONE; + int countIndex = -1; char* pSrc = (*(char**)((char*)input + tbl[index].offset)); if (pSrc == NULL) return ERR_MISSING_FIELD; + void* ptr = csonGetProperty(input, tbl[index].arrayCountField, tbl, &countIndex); + + if(ptr == NULL || countIndex == -1){ + return ERR_MISSING_FIELD; + } + long long size = getIntegerValueFromPointer(ptr, tbl[countIndex].size); + cson_t joArray = cson_array(); - size_t size = *((size_t*)csonGetProperty(input, tbl[index].arrayCountField, tbl)); + long long successCount = 0; - size_t successCount = 0; - - for (int i = 0; i < size; i++) { + for (long long i = 0; i < size; i++) { cson_t jotmp; if(tbl[index].reflect_tbl[0].field[0] == '0'){ /* field start with '0' mean basic types. */ @@ -199,6 +200,8 @@ int getJsonBool(void* input, const reflect_item_t* tbl, int index, cson_t* obj) void* pSrc = (void*)((char*)input + tbl[index].offset); + + if(tbl[index].size == sizeof(char)){ *obj = cson_bool(*((char*)pSrc)); }else if(tbl[index].size == sizeof(short)){ diff --git a/src/cson_parser.c b/src/cson_parser.c index 3f5a233..d25248e 100644 --- a/src/cson_parser.c +++ b/src/cson_parser.c @@ -3,6 +3,7 @@ * @author sun_chb@126.com */ #include "cson.h" +#include "cson_util.h" #include "string.h" #include "limits.h" #include "stdio.h" @@ -117,60 +118,17 @@ int parseJsonString(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int int parseJsonInteger(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index) { - union{ - char c; - short s; - int i; - long long l; - }ret; + int ret; + integer_val_t value; + ret = getIntegerValue(jo_tmp, tbl[index].size, &value); - long long temp; - if(cson_typeof(jo_tmp) == CSON_INTEGER){ - temp = cson_integer_value(jo_tmp); + if(ret != ERR_NONE){ + printf("Get integer failed!field:%s,errno:%d.\n", tbl[index].field, ret); }else{ - double tempDouble = cson_real_value(jo_tmp); - if(tempDouble > LLONG_MAX || tempDouble < LLONG_MIN){ - printf("value of field %s overflow.size=%ld,value=%f.\n", tbl[index].field, tbl[index].size, tempDouble); - return ERR_OVERFLOW; - }else{ - temp = tempDouble; - } + csonSetPropertyFast(output, &value, tbl + index); } - if(tbl[index].size != sizeof(char) && - tbl[index].size != sizeof(short) && - tbl[index].size != sizeof(int) && - tbl[index].size != sizeof(long long)){ - printf("Unsupported size(=%ld) of integer.\n", tbl[index].size); - printf("Please check if the type of field %s in char/short/int/long long!\n", tbl[index].field); - return ERR_OVERFLOW; - } - - if(tbl[index].size == sizeof(char) && (temp > CHAR_MAX || temp < CHAR_MIN)){ - printf("value of field %s overflow.size=%ld,value=%lld.\n", tbl[index].field, tbl[index].size, temp); - return ERR_OVERFLOW; - }else if(tbl[index].size == sizeof(short) && (temp > SHRT_MAX || temp < SHRT_MIN)){ - printf("value of field %s overflow.size=%ld,value=%lld.\n", tbl[index].field, tbl[index].size, temp); - return ERR_OVERFLOW; - }else if(tbl[index].size == sizeof(int) && (temp > INT_MAX || temp < INT_MIN)){ - printf("value of field %s overflow.size=%ld,value=%lld.\n", tbl[index].field, tbl[index].size, temp); - return ERR_OVERFLOW; - }else{ - } - - /* avoid error on big endian */ - if(tbl[index].size == sizeof(char)){ - ret.c = temp; - }else if(tbl[index].size == sizeof(short)){ - ret.s = temp; - }else if(tbl[index].size == sizeof(int)){ - ret.i = temp; - }else{ - ret.l = temp; - } - - csonSetPropertyFast(output, &ret, tbl + index); - return ERR_NONE; + return ret; } @@ -181,18 +139,26 @@ int parseJsonObject(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int int parseJsonArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index) { + printf("parseJsonArray:%s\n", tbl[index].field); size_t arraySize = cson_array_size(jo_tmp); if (arraySize == 0) { - csonSetProperty(output, tbl->arrayCountField, &arraySize, tbl); + csonSetProperty(output, tbl[index].arrayCountField, &arraySize, tbl); return ERR_NONE; } + + int countIndex = -1; + csonGetProperty(output, tbl[index].arrayCountField, tbl, &countIndex); + + if(countIndex == -1){ + return ERR_MISSING_FIELD; + } char* pMem = (char*)malloc(arraySize * tbl[index].arraySize); if (pMem == NULL) return ERR_MEMORY; - size_t successCount = 0; - for (int j = 0; j < arraySize; j++) { + long long successCount = 0; + for (size_t j = 0; j < arraySize; j++) { cson_t item = cson_array_get(jo_tmp, j); if (item != NULL) { int ret; @@ -209,14 +175,19 @@ int parseJsonArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int i } } + integer_val_t val; + if(checkIntegerValue(successCount, tbl[countIndex].size, &val) != ERR_NONE){ + successCount = 0; + } + if (successCount == 0) { - csonSetProperty(output, tbl[index].arrayCountField, &successCount, tbl); + csonSetPropertyFast(output, &successCount, tbl + countIndex); free(pMem); pMem = NULL; csonSetPropertyFast(output, &pMem, tbl + index); return ERR_MISSING_FIELD; } else { - csonSetProperty(output, tbl[index].arrayCountField, &successCount, tbl); + csonSetPropertyFast(output, &val, tbl + countIndex); csonSetPropertyFast(output, &pMem, tbl + index); return ERR_NONE; } @@ -243,35 +214,15 @@ int parseJsonReal(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int in int parseJsonBool(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index) { - if(tbl[index].size != sizeof(char) && - tbl[index].size != sizeof(short) && - tbl[index].size != sizeof(int) && - tbl[index].size != sizeof(long long)){ - printf("Unsupported size(=%ld) of bool.\n", tbl[index].size); - printf("Please check if the type of field %s in char/short/int/long long!\n", tbl[index].field); - return ERR_OVERFLOW; - } - - union{ - char c; - short s; - int i; - long long l; - }temp; - - /* avoid error on big endian */ - if(tbl[index].size == sizeof(char)){ - temp.c = cson_bool_value(jo_tmp); - }else if(tbl[index].size == sizeof(short)){ - temp.s = cson_bool_value(jo_tmp); - }else if(tbl[index].size == sizeof(int)){ - temp.i = cson_bool_value(jo_tmp); + int ret; + integer_val_t value; + ret = getIntegerValue(jo_tmp, tbl[index].size, &value); + if(ret != ERR_NONE){ + printf("Get integer failed!field:%s,errno:%d.\n", tbl[index].field, ret); }else{ - temp.l = cson_bool_value(jo_tmp); + csonSetPropertyFast(output, &value, tbl + index); } - - csonSetPropertyFast(output, &temp, tbl + index); - return ERR_NONE; + return ret; } int parseJsonObjectDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index){ diff --git a/src/cson_reflect.c b/src/cson_reflect.c index 2c95f61..7f08918 100644 --- a/src/cson_reflect.c +++ b/src/cson_reflect.c @@ -3,6 +3,7 @@ * @author sun_chb@126.com */ #include "cson_reflect.h" +#include "cson_util.h" #include "string.h" #include "stdio.h" #include "stdlib.h" @@ -27,7 +28,7 @@ const reflect_item_t boolReflectTbl[] = { {} }; -static const reflect_item_t* getReflexItem(const char* field, const reflect_item_t* tbl) +static const reflect_item_t* getReflexItem(const char* field, const reflect_item_t* tbl, int* pIndex) { const reflect_item_t* ret = NULL; @@ -35,6 +36,8 @@ static const reflect_item_t* getReflexItem(const char* field, const reflect_item if (!(tbl[i].field)) break; if (strcmp(field, tbl[i].field) == 0) { ret = &(tbl[i]); + + if(pIndex) *pIndex = i; break; } } @@ -44,10 +47,10 @@ static const reflect_item_t* getReflexItem(const char* field, const reflect_item return ret; } -void* csonGetProperty(void* obj, const char* field, const reflect_item_t* tbl) +void* csonGetProperty(void* obj, const char* field, const reflect_item_t* tbl, int* pIndex) { if (!(obj && field && tbl)) return NULL; - const reflect_item_t* ret = getReflexItem(field, tbl); + const reflect_item_t* ret = getReflexItem(field, tbl, pIndex); if (!ret) return NULL; @@ -58,7 +61,7 @@ void csonSetProperty(void* obj, const char* field, void* data, const reflect_ { if (!(obj && field && data && tbl)) return; - const reflect_item_t* ret = getReflexItem(field, tbl); + const reflect_item_t* ret = getReflexItem(field, tbl, NULL); if (!ret) return; @@ -84,7 +87,14 @@ void csonLoopProperty(void* pData, const reflect_item_t* tbl, loop_func_t func) char* pProperty = (char*)pData + tbl[i].offset; if (tbl[i].type == CSON_ARRAY) { - size_t size = *((size_t*)csonGetProperty(pData, tbl[i].arrayCountField, tbl)); + int countIndex = -1; + void* ptr = csonGetProperty(pData, tbl[i].arrayCountField, tbl, &countIndex); + + if(ptr == NULL || countIndex == -1){ + continue; + } + long long size = getIntegerValueFromPointer(ptr, tbl[countIndex].size); + for (int j = 0; j < size; j++) { csonLoopProperty(*((char**)pProperty) + j * tbl[i].arraySize, tbl[i].reflect_tbl, func); } diff --git a/src/cson_util.c b/src/cson_util.c new file mode 100644 index 0000000..6ac38fb --- /dev/null +++ b/src/cson_util.c @@ -0,0 +1,107 @@ +#include "cson_util.h" +#include "cson_interface.h" +#include "limits.h" +#include "stdio.h" + +int getIntegerValue(cson_t jo_tmp, int size, integer_val_t* i){ + long long temp; + + if(size != sizeof(char) && + size != sizeof(short) && + size != sizeof(int) && + size != sizeof(long long)){ + return ERR_OVERFLOW; + } + + if(cson_typeof(jo_tmp) == CSON_INTEGER){ + temp = cson_integer_value(jo_tmp); + }else if(cson_typeof(jo_tmp) == CSON_TRUE){ + temp = 1; + }else if(cson_typeof(jo_tmp) == CSON_FALSE){ + temp = 0; + }else if(cson_typeof(jo_tmp) == CSON_REAL){ + double tempDouble = cson_real_value(jo_tmp); + if(tempDouble > LLONG_MAX || tempDouble < LLONG_MIN){ + return ERR_OVERFLOW; + }else{ + temp = tempDouble; + } + }else{ + return ERR_ARGS; + } + + if(size == sizeof(char) && (temp > CHAR_MAX || temp < CHAR_MIN)){ + return ERR_OVERFLOW; + }else if(size == sizeof(short) && (temp > SHRT_MAX || temp < SHRT_MIN)){ + return ERR_OVERFLOW; + }else if(size == sizeof(int) && (temp > INT_MAX || temp < INT_MIN)){ + return ERR_OVERFLOW; + }else{ + } + + /* avoid error on big endian */ + if(size == sizeof(char)){ + i->c = temp; + }else if(size == sizeof(short)){ + + i->s = temp; + }else if(size == sizeof(int)){ + i->i = temp; + }else{ + i->l = temp; + } + + return ERR_NONE; +} + +int checkIntegerValue(long long val, int size, integer_val_t* i){ + if(size != sizeof(char) && + size != sizeof(short) && + size != sizeof(int) && + size != sizeof(long long)){ + return ERR_OVERFLOW; + } + + if(size == sizeof(char) && (val > CHAR_MAX || val < CHAR_MIN)){ + return ERR_OVERFLOW; + }else if(size == sizeof(short) && (val > SHRT_MAX || val < SHRT_MIN)){ + return ERR_OVERFLOW; + }else if(size == sizeof(int) && (val > INT_MAX || val < INT_MIN)){ + return ERR_OVERFLOW; + }else{ + } + + /* avoid error on big endian */ + if(size == sizeof(char)){ + i->c = val; + }else if(size == sizeof(short)){ + + i->s = val; + }else if(size == sizeof(int)){ + i->i = val; + }else{ + i->l = val; + } + + return ERR_NONE; +} + +long long getIntegerValueFromPointer(void* ptr, int size){ + long long ret = 0; + + if(!ptr) return 0; + + if(size == sizeof(char)){ + ret = *((char*)ptr); + }else if(size == sizeof(short)){ + ret = *((short*)ptr); + }else if(size == sizeof(int)){ + ret = *((int*)ptr); + }else if(size == sizeof(long long)){ + ret = *((long long*)ptr); + }else{ + printf("Unsupported size(=%d) of integer.\n", size); + } + + return ret; +} \ No newline at end of file