Skip to content
Permalink
Browse files
fixed json rpc memory leak
  • Loading branch information
xuzhenbao committed Feb 16, 2022
1 parent ca74a95 commit 004b9dad5cf233bba4ce3c105163b2079c8873d1
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 36 deletions.
@@ -98,6 +98,10 @@ static void stdLog(void*, int level, const char *file, int line, const char *msg
return 0;
}

int addFailed(void*, double , double , double *) {
return 0x02000001;// return customer error
}

int getName_example4(void*, char** result) {
*result = strdup("allocatedInFunction");
return 0;
@@ -198,6 +202,25 @@ static void stdLog(void*, int level, const char *file, int line, const char *msg
dynInterface_destroy(intf);
}

void callFailedTestPreAllocated(void) {
dyn_interface_type *intf = nullptr;
FILE *desc = fopen("descriptors/example1.descriptor", "r");
ASSERT_TRUE(desc != nullptr);
int rc = dynInterface_parse(desc, &intf);
ASSERT_EQ(0, rc);
fclose(desc);

char *result = nullptr;
tst_serv serv {nullptr, addFailed, nullptr, nullptr, nullptr};

rc = jsonRpc_call(intf, &serv, R"({"m":"add(DD)D", "a": [1.0,2.0]})", &result);
ASSERT_EQ(0, rc);
ASSERT_TRUE(strstr(result, "e") != nullptr);

free(result);
dynInterface_destroy(intf);
}

void callTestOutput(void) {
dyn_interface_type *intf = nullptr;
FILE *desc = fopen("descriptors/example1.descriptor", "r");
@@ -404,6 +427,10 @@ TEST_F(JsonRpcTests, callPre) {
callTestPreAllocated();
}

TEST_F(JsonRpcTests, callFailedPre) {
callFailedTestPreAllocated();
}

TEST_F(JsonRpcTests, callOut) {
callTestOutput();
}
@@ -177,52 +177,50 @@ int jsonRpc_call(dyn_interface_type *intf, void *service, const char *request, c
}

//serialize and free output
if (funcCallStatus == 0 && status == OK) {
for (i = 0; i < nrOfArgs; i += 1) {
dyn_type *argType = dynFunction_argumentTypeForIndex(func, i);
enum dyn_function_argument_meta meta = dynFunction_argumentMetaForIndex(func, i);
if (meta == DYN_FUNCTION_ARGUMENT_META__PRE_ALLOCATED_OUTPUT) {
for (i = 0; i < nrOfArgs; i += 1) {
dyn_type *argType = dynFunction_argumentTypeForIndex(func, i);
enum dyn_function_argument_meta meta = dynFunction_argumentMetaForIndex(func, i);
if (meta == DYN_FUNCTION_ARGUMENT_META__PRE_ALLOCATED_OUTPUT) {
if (funcCallStatus == 0 && status == OK) {
status = jsonSerializer_serializeJson(argType, args[i], &jsonResult);
}
dyn_type *subType = NULL;
dynType_typedPointer_getTypedType(argType, &subType);
void **ptrToInst = (void**)args[i];
dynType_free(subType, *ptrToInst);
free(ptrToInst);
} else if (meta == DYN_FUNCTION_ARGUMENT_META__OUTPUT) {
if (funcCallStatus == 0 && ptr != NULL) {
dyn_type *typedType = NULL;
if (status == OK) {
status = jsonSerializer_serializeJson(argType, args[i], &jsonResult);
status = dynType_typedPointer_getTypedType(argType, &typedType);
}
dyn_type *subType = NULL;
dynType_typedPointer_getTypedType(argType, &subType);
void **ptrToInst = (void**)args[i];
dynType_free(subType, *ptrToInst);
free(ptrToInst);
} else if (meta == DYN_FUNCTION_ARGUMENT_META__OUTPUT) {
if (ptr != NULL) {
dyn_type *typedType = NULL;
if (status == OK && dynType_descriptorType(typedType) == 't') {
status = jsonSerializer_serializeJson(typedType, (void*) &ptr, &jsonResult);
free(ptr);
} else {
dyn_type *typedTypedType = NULL;
if (status == OK) {
status = dynType_typedPointer_getTypedType(argType, &typedType);
status = dynType_typedPointer_getTypedType(typedType, &typedTypedType);
}
if (dynType_descriptorType(typedType) == 't') {
status = jsonSerializer_serializeJson(typedType, (void*) &ptr, &jsonResult);
free(ptr);
} else {
dyn_type *typedTypedType = NULL;
if (status == OK) {
status = dynType_typedPointer_getTypedType(typedType, &typedTypedType);
}

if(status == OK){
status = jsonSerializer_serializeJson(typedTypedType, ptr, &jsonResult);
}

if (status == OK) {
dynType_free(typedTypedType, ptr);
}

if(status == OK){
status = jsonSerializer_serializeJson(typedTypedType, ptr, &jsonResult);
}

} else {
LOG_DEBUG("Output ptr is null");
if (status == OK) {
dynType_free(typedTypedType, ptr);
}
}
}

if (status != OK) {
break;
} else {
LOG_DEBUG("Output ptr is null");
}
}

if (status != OK) {
break;
}
}

char *response = NULL;
@@ -102,6 +102,50 @@ const char* celix_strerror(celix_status_t status);

#define CELIX_ENOMEM ENOMEM

/*!
* @brief Error code has 32bits, its internal structure as following
*
*|31-30bit|29bit|28-27bit|26-16bit|15-0bit|
*|--------|-----|--------|--------|-------|
*|R |C |R |Facility|Code |
*
* C (1bit): Customer. If set, indicates that the error code is customer-defined. If clear, indicates that the error code is celix-defines
* R : Reserved. It should be set to 0
* Facility (11 bits): An indicator of the source of the error
*
*/

/*!
* @brief Customer error code mask
*
*/
#define CELIX_CUSTOMER_ERR_MASK 0x02000000

/*!
* @brief The facility of system error code,
* @note Error code 0 indicates success,it is not system error code.
*/
#define CELIX_FACILITY_SYSTEM 0

/*!
* @brief The facility of celix default error code
*
*/
#define CELIX_FACILITY_NULL 1

/*!
* @brief The facility of the rpc subsystem error code
*
*/
#define CELIX_FACILITY_RPC 2

/*!
* @brief The facility of the http suppoter error code
*
*/
#define CELIX_FACILITY_HTTP 3


/**
* \}
*/

0 comments on commit 004b9da

Please sign in to comment.