Ver código fonte

fix jrpc call fun with 0 pars, fix mem lack in some branch

Lyon 1 ano atrás
pai
commit
92cdb97af5

+ 63 - 43
package/jrpc/jrpc.c

@@ -468,6 +468,7 @@ cJSON* JRPC_send_request_blocking(JRPC* self,
                                   cJSON* params[],
                                   int param_count) {
     // Build request
+    cJSON* resObj = NULL;
     int id = ++self->current_id;
     cJSON* request = cJSON_CreateObject();
     cJSON_AddStringToObject(request, STR_JSON_RPC_FIELD, STR_JSON_RPC_VERSION);
@@ -488,9 +489,8 @@ cJSON* JRPC_send_request_blocking(JRPC* self,
     if (JRPC_send_message_with_retry(self, request_str, RETRY_COUNT,
                                      ACK_TIMEOUT, id, TYPE_ACK,
                                      "Client") != 0) {
-        jrpc_free(request_str);
-        cJSON_Delete(request);
-        return NULL;
+        resObj = NULL;
+        goto __exit;
     }
     JRPC_send_acknowledgement(self, id, ACK_SUCCESS, "Client");
     // Wait for response
@@ -499,21 +499,25 @@ cJSON* JRPC_send_request_blocking(JRPC* self,
         cJSON* response_json =
             JRPC_receive_with_id_and_type(self, id, TYPE_RESULT);
         if (response_json != NULL) {
-            cJSON_Delete(request);
-            jrpc_free(request_str);
             char* response_str = cJSON_Print(response_json);
             jrpc_debug("[Client] Received Response: %s\n", response_str);
             jrpc_free(response_str);
-            return response_json;
+            resObj = response_json;
+            goto __exit;
         }
         if (self->tick() - start_time >= BLOCKING_TIMEOUT) {
             jrpc_debug("[Client] Response timeout\n");
-            jrpc_free(request_str);
-            cJSON_Delete(request);
-            return NULL;
+            resObj = NULL;
+            goto __exit;
         }
         self->yield();  // Thread switch
     }
+__exit:
+    cJSON_Delete(request);
+    if (NULL != request_str) {
+        jrpc_free(request_str);
+    }
+    return resObj;
 }
 
 // Mock send function with validation
@@ -727,63 +731,77 @@ char* jrpc_strtok(char* str, const char* delimiters, char** context) {
 }
 
 char* JRPC_cmd(JRPC* jrpc, const char* cmd) {
-    char* cmd_copy = jrpc_strdup(cmd);
-    char* context = NULL;
+    char* cmd_copy = NULL;
+    char* method = NULL;
+    cJSON* params_array[10] = {NULL};
+    int param_count = 0;
+    char* result_str = NULL;
+    cJSON* result = NULL;
+
+    cmd_copy = jrpc_strdup(cmd);
+    if (!cmd_copy) {
+        jrpc_debug("Failed to duplicate command\n");
+        goto __exit;
+    }
 
+    char* context = NULL;
     char* token = jrpc_strtok(cmd_copy, " ", &context);
     if (token == NULL) {
         jrpc_debug("Invalid command\n");
-        jrpc_free(cmd_copy);
-        return NULL;
+        goto __exit;
     }
 
-    char* method = jrpc_strdup(token);
+    method = jrpc_strdup(token);
+    if (!method) {
+        jrpc_debug("Failed to duplicate method\n");
+        goto __exit;
+    }
 
-    cJSON* params_array[10];
-    int param_count = 0;
     while ((token = jrpc_strtok(NULL, " ", &context)) != NULL) {
         int param_value = atoi(token);
         params_array[param_count] = cJSON_CreateNumber(param_value);
+        if (!params_array[param_count]) {
+            jrpc_debug("Failed to create JSON number\n");
+            goto __exit;
+        }
         param_count++;
     }
 
-    if (param_count == 0) {
-        jrpc_debug("No parameters provided\n");
-        jrpc_free(method);
-        jrpc_free(cmd_copy);
-        return NULL;
-    }
-
-    cJSON* result =
+    result =
         JRPC_send_request_blocking(jrpc, method, params_array, param_count);
-
     if (result == NULL) {
-        jrpc_debug("No result\n", NULL);
-        jrpc_free(method);
-        jrpc_free(cmd_copy);
-        return NULL;
+        jrpc_debug("No result\n");
+        goto __exit;
     }
 
     cJSON* result_data = cJSON_GetObjectItem(result, "result");
-    if (NULL == result_data) {
-        jrpc_debug("No result Item\n", NULL);
-        jrpc_free(method);
-        jrpc_free(cmd_copy);
-        cJSON_Delete(result);
-        return NULL;
+    if (result_data == NULL) {
+        jrpc_debug("No result item\n");
+        goto __exit;
     }
 
-    char* result_str = NULL;
-    if (result_data) {
-        result_str = cJSON_Print(result_data);
-        // jrpc_debug("%s\n", result_str);
-        cJSON_Delete(result);
+    result_str = cJSON_Print(result_data);
+    if (!result_str) {
+        jrpc_debug("Failed to print JSON result\n");
+        goto __exit;
     }
+
+__exit:
     for (int i = 0; i < param_count; i++) {
-        cJSON_Delete(params_array[i]);
+        if (params_array[i]) {
+            cJSON_Delete(params_array[i]);
+        }
+    }
+    if (result) {
+        cJSON_Delete(result);
+    }
+    if (method) {
+        jrpc_free(method);
+    }
+    if (cmd_copy) {
+        jrpc_free(cmd_copy);
     }
-    jrpc_free(method);
-    jrpc_free(cmd_copy);
+
     return result_str;
 }
 
@@ -810,5 +828,7 @@ void JRPC_init(JRPC* jrpc,
 void JRPC_deinit(JRPC* jrpc) {
     for (int i = 0; i < jrpc->cache_count; i++) {
         cJSON_Delete(jrpc->cache[i]);
+        jrpc->cache[i] = NULL;
     }
+    jrpc->cache_count = 0;
 }

+ 63 - 43
port/linux/package/pikascript/pikascript-lib/jrpc/jrpc.c

@@ -468,6 +468,7 @@ cJSON* JRPC_send_request_blocking(JRPC* self,
                                   cJSON* params[],
                                   int param_count) {
     // Build request
+    cJSON* resObj = NULL;
     int id = ++self->current_id;
     cJSON* request = cJSON_CreateObject();
     cJSON_AddStringToObject(request, STR_JSON_RPC_FIELD, STR_JSON_RPC_VERSION);
@@ -488,9 +489,8 @@ cJSON* JRPC_send_request_blocking(JRPC* self,
     if (JRPC_send_message_with_retry(self, request_str, RETRY_COUNT,
                                      ACK_TIMEOUT, id, TYPE_ACK,
                                      "Client") != 0) {
-        jrpc_free(request_str);
-        cJSON_Delete(request);
-        return NULL;
+        resObj = NULL;
+        goto __exit;
     }
     JRPC_send_acknowledgement(self, id, ACK_SUCCESS, "Client");
     // Wait for response
@@ -499,21 +499,25 @@ cJSON* JRPC_send_request_blocking(JRPC* self,
         cJSON* response_json =
             JRPC_receive_with_id_and_type(self, id, TYPE_RESULT);
         if (response_json != NULL) {
-            cJSON_Delete(request);
-            jrpc_free(request_str);
             char* response_str = cJSON_Print(response_json);
             jrpc_debug("[Client] Received Response: %s\n", response_str);
             jrpc_free(response_str);
-            return response_json;
+            resObj = response_json;
+            goto __exit;
         }
         if (self->tick() - start_time >= BLOCKING_TIMEOUT) {
             jrpc_debug("[Client] Response timeout\n");
-            jrpc_free(request_str);
-            cJSON_Delete(request);
-            return NULL;
+            resObj = NULL;
+            goto __exit;
         }
         self->yield();  // Thread switch
     }
+__exit:
+    cJSON_Delete(request);
+    if (NULL != request_str) {
+        jrpc_free(request_str);
+    }
+    return resObj;
 }
 
 // Mock send function with validation
@@ -727,63 +731,77 @@ char* jrpc_strtok(char* str, const char* delimiters, char** context) {
 }
 
 char* JRPC_cmd(JRPC* jrpc, const char* cmd) {
-    char* cmd_copy = jrpc_strdup(cmd);
-    char* context = NULL;
+    char* cmd_copy = NULL;
+    char* method = NULL;
+    cJSON* params_array[10] = {NULL};
+    int param_count = 0;
+    char* result_str = NULL;
+    cJSON* result = NULL;
+
+    cmd_copy = jrpc_strdup(cmd);
+    if (!cmd_copy) {
+        jrpc_debug("Failed to duplicate command\n");
+        goto __exit;
+    }
 
+    char* context = NULL;
     char* token = jrpc_strtok(cmd_copy, " ", &context);
     if (token == NULL) {
         jrpc_debug("Invalid command\n");
-        jrpc_free(cmd_copy);
-        return NULL;
+        goto __exit;
     }
 
-    char* method = jrpc_strdup(token);
+    method = jrpc_strdup(token);
+    if (!method) {
+        jrpc_debug("Failed to duplicate method\n");
+        goto __exit;
+    }
 
-    cJSON* params_array[10];
-    int param_count = 0;
     while ((token = jrpc_strtok(NULL, " ", &context)) != NULL) {
         int param_value = atoi(token);
         params_array[param_count] = cJSON_CreateNumber(param_value);
+        if (!params_array[param_count]) {
+            jrpc_debug("Failed to create JSON number\n");
+            goto __exit;
+        }
         param_count++;
     }
 
-    if (param_count == 0) {
-        jrpc_debug("No parameters provided\n");
-        jrpc_free(method);
-        jrpc_free(cmd_copy);
-        return NULL;
-    }
-
-    cJSON* result =
+    result =
         JRPC_send_request_blocking(jrpc, method, params_array, param_count);
-
     if (result == NULL) {
-        jrpc_debug("No result\n", NULL);
-        jrpc_free(method);
-        jrpc_free(cmd_copy);
-        return NULL;
+        jrpc_debug("No result\n");
+        goto __exit;
     }
 
     cJSON* result_data = cJSON_GetObjectItem(result, "result");
-    if (NULL == result_data) {
-        jrpc_debug("No result Item\n", NULL);
-        jrpc_free(method);
-        jrpc_free(cmd_copy);
-        cJSON_Delete(result);
-        return NULL;
+    if (result_data == NULL) {
+        jrpc_debug("No result item\n");
+        goto __exit;
     }
 
-    char* result_str = NULL;
-    if (result_data) {
-        result_str = cJSON_Print(result_data);
-        // jrpc_debug("%s\n", result_str);
-        cJSON_Delete(result);
+    result_str = cJSON_Print(result_data);
+    if (!result_str) {
+        jrpc_debug("Failed to print JSON result\n");
+        goto __exit;
     }
+
+__exit:
     for (int i = 0; i < param_count; i++) {
-        cJSON_Delete(params_array[i]);
+        if (params_array[i]) {
+            cJSON_Delete(params_array[i]);
+        }
+    }
+    if (result) {
+        cJSON_Delete(result);
+    }
+    if (method) {
+        jrpc_free(method);
+    }
+    if (cmd_copy) {
+        jrpc_free(cmd_copy);
     }
-    jrpc_free(method);
-    jrpc_free(cmd_copy);
+
     return result_str;
 }
 
@@ -810,5 +828,7 @@ void JRPC_init(JRPC* jrpc,
 void JRPC_deinit(JRPC* jrpc) {
     for (int i = 0; i < jrpc->cache_count; i++) {
         cJSON_Delete(jrpc->cache[i]);
+        jrpc->cache[i] = NULL;
     }
+    jrpc->cache_count = 0;
 }

+ 74 - 0
port/linux/test/module-test.cpp

@@ -947,6 +947,11 @@ rpc_mapping gtest_rpc_map[] = {{"add",
                                     return cJSON_CreateNumber(a + b);
                                 },
                                 2},
+                               {"get_val",
+                                [](cJSON* params[], int param_count) -> cJSON* {
+                                    return cJSON_CreateNumber(2478);
+                                },
+                                0},
                                RPC_MAP_END};
 
 rpc_mapping_nonblocking gtest_nonblocking_rpc_map[] = {RPC_MAP_END};
@@ -1143,6 +1148,7 @@ TEST(jrpc, BlockingRequestBetweenTwoJRPC) {
                    0};
 
     // Create a thread to run server_handle
+    server_running = 1;
     std::thread server_thread(server_handle, &server);
 
     // Client sends request to Server
@@ -1239,4 +1245,72 @@ TEST(jrpc, cmd) {
     }
 }
 
+char* execute_cmd(const char* cmd) {
+    // Server JRPC
+    JRPC server = {gtest_rpc_map,
+                   gtest_nonblocking_rpc_map,
+                   jrpc_server_send,
+                   jrpc_server_receive,
+                   1,
+                   mock_yield,
+                   mock_tick_ms,
+                   0,
+                   {NULL},
+                   0};
+
+    // Client JRPC
+    JRPC client = {gtest_rpc_map,
+                   gtest_nonblocking_rpc_map,
+                   jrpc_client_send,
+                   jrpc_client_receive,
+                   1,
+                   mock_yield,
+                   mock_tick_ms,
+                   0,
+                   {NULL},
+                   0};
+
+    // Create a thread to run server_handle
+    server_running = 1;
+    std::thread server_thread(server_handle, &server);
+
+    // Client sends request to Server
+    char* response = JRPC_cmd(&client, cmd);
+
+    // Signal the server to stop and wait for the server thread to finish
+    server_running = false;
+    server_thread.join();
+
+    // Clean up mock_sent_message
+    if (NULL != mock_sent_message) {
+        free(mock_sent_message);
+        mock_sent_message = NULL;
+    }
+
+    if (NULL != server_receive_buffer) {
+        free(server_receive_buffer);
+        server_receive_buffer = NULL;
+    }
+
+    JRPC_deinit(&server);
+    return response;
+}
+
+TEST(jrpc, exec_add) {
+    char* response = execute_cmd("add 10 20");
+    EXPECT_STREQ(response, "30");
+    free(response);
+}
+
+TEST(jrpc, exec_get_val) {
+    char* response = execute_cmd("get_val");
+    EXPECT_STREQ(response, "2478");
+    free(response);
+}
+
+TEST(jrpc, exec_par_num_err) {
+    char* response = execute_cmd("get_val 123");
+    EXPECT_STREQ(response, NULL);
+}
+
 TEST_END