From 359eec19142dea477c5f0f7bc8a78caac4af2be5 Mon Sep 17 00:00:00 2001 From: Fancy code <258828110.@qq.com> Date: Wed, 28 Feb 2024 05:54:49 -0800 Subject: [PATCH] Fixed:memory leaks bug about open source code. --- external/httpserver.h-master/src/io_events.c | 5 ++ external/httpserver.h-master/src/server.c | 4 +- middleware/AppManager/CMakeLists.txt | 2 +- middleware/AppManager/src/AppManager.cpp | 46 +++++++++- middleware/AppManager/src/AppManager.h | 14 ++- test/middleware/AppManager/CMakeLists.txt | 87 +++++++++++++++++++ test/middleware/AppManager/mainTest.cpp | 23 +++++ .../AppManager/src/AppManager_Test.cpp | 56 ++++++++++++ test/middleware/CMakeLists.txt | 3 +- test/middleware/DeviceManager/CMakeLists.txt | 2 - .../FxHttpServer/src/FxHttpServer_Test.cpp | 4 +- utils/FxHttpServer/README.md | 40 ++++++++- utils/FxHttpServer/include/FxHttpServer.h | 1 + utils/FxHttpServer/src/FxHttpServer.c | 6 ++ 14 files changed, 277 insertions(+), 16 deletions(-) create mode 100644 test/middleware/AppManager/CMakeLists.txt create mode 100644 test/middleware/AppManager/mainTest.cpp create mode 100644 test/middleware/AppManager/src/AppManager_Test.cpp diff --git a/external/httpserver.h-master/src/io_events.c b/external/httpserver.h-master/src/io_events.c index e83b12fb..4481d9a3 100644 --- a/external/httpserver.h-master/src/io_events.c +++ b/external/httpserver.h-master/src/io_events.c @@ -82,6 +82,11 @@ void _hs_accept_and_begin_request_cycle(http_server_t *server, } else { hs_request_begin_read(request); } + // ================ added by xiao ================ // + if (request) { + hs_request_terminate_connection(request); + } + // ================ added by xiao end ================ // } } diff --git a/external/httpserver.h-master/src/server.c b/external/httpserver.h-master/src/server.c index 355a0ec2..46238c87 100644 --- a/external/httpserver.h-master/src/server.c +++ b/external/httpserver.h-master/src/server.c @@ -102,11 +102,11 @@ void _hs_add_server_sock_events(http_server_t *serv) { ev.data.ptr = serv; epoll_ctl(serv->loop, EPOLL_CTL_ADD, serv->socket, &ev); } - +int gHttpServerRuning = 1; int hs_server_run_event_loop(http_server_t *serv, const char *ipaddr) { hs_server_listen_on_addr(serv, ipaddr); struct epoll_event ev_list[1]; - while (1) { + while (gHttpServerRuning) { int nev = epoll_wait(serv->loop, ev_list, 1, -1); for (int i = 0; i < nev; i++) { ev_cb_t *ev_cb = (ev_cb_t *)ev_list[i].data.ptr; diff --git a/middleware/AppManager/CMakeLists.txt b/middleware/AppManager/CMakeLists.txt index 873dbbcf..49c11d1c 100644 --- a/middleware/AppManager/CMakeLists.txt +++ b/middleware/AppManager/CMakeLists.txt @@ -8,7 +8,7 @@ include_directories( ./include ${UTILS_SOURCE_PATH}/StatusCode/include ${UTILS_SOURCE_PATH}/Log/include - ${UTILS_SOURCE_PATH}/LedControl/include + ${UTILS_SOURCE_PATH}/FxHttpServer/include ${HAL_SOURCE_PATH}/include ) #do not rely on any other library diff --git a/middleware/AppManager/src/AppManager.cpp b/middleware/AppManager/src/AppManager.cpp index a09d61dc..8a107203 100644 --- a/middleware/AppManager/src/AppManager.cpp +++ b/middleware/AppManager/src/AppManager.cpp @@ -13,7 +13,47 @@ * limitations under the License. */ #include "AppManager.h" +#include "FxHttpServer.h" #include "ILog.h" -#include -const StatusCode AppManager::Init(void) { return CreateStatusCode(STATUS_CODE_OK); } -const StatusCode AppManager::UnInit(void) { return CreateStatusCode(STATUS_CODE_OK); } +AppManager::AppManager() +{ + // + // mHttpServerRuning = false; +} +const StatusCode AppManager::Init(void) +{ + HttpServerStart(); + return CreateStatusCode(STATUS_CODE_OK); +} +const StatusCode AppManager::UnInit(void) +{ + HttpServerStop(); + return CreateStatusCode(STATUS_CODE_OK); +} +void AppManager::HttpServerStart(void) +{ + auto httpServerThread = [](std::shared_ptr app) { + LogInfo("AppManager httpServer started.\n"); + app->HttpServerThread(); + }; + mHttpSever = std::thread(httpServerThread, shared_from_this()); +} +void AppManager::HttpServerStop(void) +{ + FxHttpServerExit(); + if (mHttpSever.joinable()) { + mHttpSever.join(); + } +} +void AppManager::HttpServerThread(void) +{ + // typedef void (*HttpHandleCallback)(const char *, const unsigned int, ResponseHandle, void *); + std::shared_ptr app = shared_from_this(); + auto httpHandle = + [](const char *url, const unsigned int urlLength, ResponseHandle responseHandle, void *context) -> void { + // + LogInfo("=============================== url = %s\n", url); + }; + FxHttpServerInit(httpHandle); + FxHttpServerUnInit(); +} diff --git a/middleware/AppManager/src/AppManager.h b/middleware/AppManager/src/AppManager.h index 28f7de4b..46b4117e 100644 --- a/middleware/AppManager/src/AppManager.h +++ b/middleware/AppManager/src/AppManager.h @@ -15,17 +15,23 @@ #ifndef APP_MANAGER_H #define APP_MANAGER_H #include "IAppManager.h" -class AppManager : public IAppManager +#include +class AppManager : public IAppManager, public std::enable_shared_from_this { public: - AppManager() = default; + AppManager(); virtual ~AppManager() = default; - const StatusCode Init(void) override; const StatusCode UnInit(void) override; private: - // std::vector> mLedManagers; + void HttpServerStart(void); + void HttpServerStop(void); + void HttpServerThread(void); + +private: + // bool mHttpServerRuning; + std::thread mHttpSever; }; #endif diff --git a/test/middleware/AppManager/CMakeLists.txt b/test/middleware/AppManager/CMakeLists.txt new file mode 100644 index 00000000..b69487ed --- /dev/null +++ b/test/middleware/AppManager/CMakeLists.txt @@ -0,0 +1,87 @@ +# include(${CMAKE_SOURCE_DIR}/build/independent_source.cmake) +include(${CMAKE_SOURCE_DIR_IPCSDK}/build/global_config.cmake) +set(EXECUTABLE_OUTPUT_PATH ${TEST_OUTPUT_PATH}/bin) + +include_directories( + ./src + ./include + ./tool/include + ${UTILS_SOURCE_PATH}/Log/include + ${UTILS_SOURCE_PATH}/StatusCode/include + # ${UTILS_SOURCE_PATH}/UartDevice/include + # ${UTILS_SOURCE_PATH}/McuProtocol/include + ${UTILS_SOURCE_PATH}/KeyControl/include + ${UTILS_SOURCE_PATH}/LedControl/include + ${HAL_SOURCE_PATH}/include + # ${HAL_SOURCE_PATH}/src + ${MIDDLEWARE_SOURCE_PATH}/AppManager/include + ${MIDDLEWARE_SOURCE_PATH}/AppManager/src + # ${MIDDLEWARE_SOURCE_PATH}/McuAskBase/include + # ${TEST_SOURCE_PATH}/utils/LinuxApiMock/include + ${TEST_SOURCE_PATH}/hal/tool/include + # ${TEST_SOURCE_PATH}/utils/UartDevice/tool/include + # ${TEST_SOURCE_PATH}/utils/McuProtocol/tool/include + # ${TEST_SOURCE_PATH}/middleware/McuAskBase/tool/include + ${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googletest/include + ${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googlemock/include +) + +link_directories( + ${LIBS_OUTPUT_PATH} + ${EXTERNAL_LIBS_OUTPUT_PATH} +) + +aux_source_directory(. SRC_FILES_MAIN) +aux_source_directory(./src SRC_FILES) +if(${TARGET_PLATFORM} MATCHES ${DEFINE_LINUX}) + aux_source_directory(./src_mock SRC_FILES) +endif() + +set(TARGET_NAME AppManagerTest) +add_executable(${TARGET_NAME} ${SRC_FILES_MAIN} ${SRC_FILES}) +target_link_libraries(${TARGET_NAME} AppManager gtest gmock pthread) +if(${TEST_COVERAGE} MATCHES "true") + target_link_libraries(${TARGET_NAME} gcov) +endif() + +if ("${CLANG_TIDY_SUPPORT}" MATCHES "true") +add_custom_target( + AppManagerTest_code_check + COMMAND ${CLANG_TIDY_EXE} + -checks='${CLANG_TIDY_CHECKS}' + --header-filter=.* + --system-headers=false + ${SRC_FILES} + ${CLANG_TIDY_CONFIG} + # --line-filter='[{\"name\":\"${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googletest/include/getest/gtest.h\"}]' + --line-filter='[{\"name\":\"${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googletest/include/getest/*.h\"}]' + -p ${PLATFORM_PATH}/cmake-shell + WORKING_DIRECTORY ${TEST_SOURCE_PATH}/middleware/AppManager +) +add_custom_command( + TARGET ${TARGET_NAME} + PRE_BUILD + COMMAND make AppManagerTest_code_check + WORKING_DIRECTORY ${PLATFORM_PATH}/cmake-shell/ +) + +file(GLOB_RECURSE HEADER_FILES *.h) +add_custom_target( + AppManagerTest_code_format + COMMAND ${CLANG_FORMAT_EXE} + -style=file + -i ${SRC_FILES} ${SRC_FILES_MAIN} ${HEADER_FILES} + WORKING_DIRECTORY ${TEST_SOURCE_PATH}/middleware/AppManager +) +add_custom_command( + TARGET ${TARGET_NAME} + PRE_BUILD + COMMAND make AppManagerTest_code_check + COMMAND make AppManagerTest_code_format + WORKING_DIRECTORY ${PLATFORM_PATH}/cmake-shell/ +) +endif() + +define_file_name(${TARGET_NAME}) + +# add_subdirectory(tool) \ No newline at end of file diff --git a/test/middleware/AppManager/mainTest.cpp b/test/middleware/AppManager/mainTest.cpp new file mode 100644 index 00000000..475ceee4 --- /dev/null +++ b/test/middleware/AppManager/mainTest.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2023 Fancy Code. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +int main(int argc, char *argv[]) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/test/middleware/AppManager/src/AppManager_Test.cpp b/test/middleware/AppManager/src/AppManager_Test.cpp new file mode 100644 index 00000000..1750ece2 --- /dev/null +++ b/test/middleware/AppManager/src/AppManager_Test.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2023 Fancy Code. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "IAppManager.h" +#include "ILog.h" +#include +#include +#include +namespace AppManagerTest +{ +class AppManagerTest : public testing::Test +{ +public: + AppManagerTest() {} + virtual ~AppManagerTest() {} + static void SetUpTestCase() + { + CreateLogModule(); + ILogInit(LOG_INSTANCE_TYPE_END); + } + static void TearDownTestCase() { ILogUnInit(); } + virtual void SetUp() + { + // CreateAllKeysMcok(); + // HalTestTool::Init(); + // AppManagerTestTool::Init(); + // CreateHalCppModule(); + CreateAppManagerModule(); + } + virtual void TearDown() + { + // HalTestTool::UnInit(); + // AppManagerTestTool::UnInit(); + DestroyAppManagerModule(); + // DestroyAllKeysMock(); + } +}; +// ../output_files/test/bin/AppManagerTest --gtest_filter=AppManagerTest.INTEGRATION_AppManager_EXAMPLE_Demo +TEST_F(AppManagerTest, INTEGRATION_AppManager_EXAMPLE_Demo) +{ + IAppManager::GetInstance()->Init(); + std::this_thread::sleep_for(std::chrono::milliseconds(10000)); + IAppManager::GetInstance()->UnInit(); +} +} // namespace AppManagerTest \ No newline at end of file diff --git a/test/middleware/CMakeLists.txt b/test/middleware/CMakeLists.txt index f6731ccc..5d98a8d2 100644 --- a/test/middleware/CMakeLists.txt +++ b/test/middleware/CMakeLists.txt @@ -3,4 +3,5 @@ add_subdirectory(IpcConfig) add_subdirectory(McuManager) add_subdirectory(McuAskBase) -add_subdirectory(DeviceManager) \ No newline at end of file +add_subdirectory(DeviceManager) +add_subdirectory(AppManager) \ No newline at end of file diff --git a/test/middleware/DeviceManager/CMakeLists.txt b/test/middleware/DeviceManager/CMakeLists.txt index d5747c3b..560518de 100644 --- a/test/middleware/DeviceManager/CMakeLists.txt +++ b/test/middleware/DeviceManager/CMakeLists.txt @@ -31,8 +31,6 @@ link_directories( ${EXTERNAL_LIBS_OUTPUT_PATH} ) - - aux_source_directory(. SRC_FILES_MAIN) aux_source_directory(./src SRC_FILES) if(${TARGET_PLATFORM} MATCHES ${DEFINE_LINUX}) diff --git a/test/utils/FxHttpServer/src/FxHttpServer_Test.cpp b/test/utils/FxHttpServer/src/FxHttpServer_Test.cpp index 15ce352c..84086edf 100644 --- a/test/utils/FxHttpServer/src/FxHttpServer_Test.cpp +++ b/test/utils/FxHttpServer/src/FxHttpServer_Test.cpp @@ -36,8 +36,8 @@ void HttpHandle(const char *url, const unsigned int urlLength, ResponseHandle re } } } -// ../output_files/test/bin/FxHttpServerTest --gtest_filter=FxHttpServerTest.Demo -TEST(FxHttpServerTest, Demo) +// ../output_files/test/bin/FxHttpServerTest --gtest_filter=FxHttpServerTest.INTEGRATION_AppManager_EXAMPLE_Demo +TEST(FxHttpServerTest, INTEGRATION_AppManager_EXAMPLE_Demo) { CreateLogModule(); ILogInit(LOG_INSTANCE_TYPE_END); diff --git a/utils/FxHttpServer/README.md b/utils/FxHttpServer/README.md index 58ca3aee..6cb96ceb 100644 --- a/utils/FxHttpServer/README.md +++ b/utils/FxHttpServer/README.md @@ -21,4 +21,42 @@ add_custom_command( ``` PUBLIC $<$:-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all> ``` -4. \ No newline at end of file +4. 由于开源代码不支持安全退出,所以修改了开源代码; +``` +int gHttpServerRuning = 1; // 增加一个运行标识 +int hs_server_run_event_loop(http_server_t *serv, const char *ipaddr) { + hs_server_listen_on_addr(serv, ipaddr); + struct epoll_event ev_list[1]; + while (gHttpServerRuning) { // 运行标识赋值为0时,httpserver退出 + int nev = epoll_wait(serv->loop, ev_list, 1, -1); + for (int i = 0; i < nev; i++) { + ev_cb_t *ev_cb = (ev_cb_t *)ev_list[i].data.ptr; + ev_cb->handler(&ev_list[i]); + } + } + return 0; +} +``` +5. 修复一个内存安全漏洞; +``` +void _hs_accept_and_begin_request_cycle(http_server_t *server, + hs_io_cb_t on_client_connection_cb, + hs_io_cb_t on_timer_event_cb) { + http_request_t *request = NULL; + while ((request = hs_server_accept_connection(server, on_client_connection_cb, + on_timer_event_cb))) { + if (server->memused > HTTP_MAX_TOTAL_EST_MEM_USAGE) { + hs_request_respond_error(request, 503, "Service Unavailable", + hs_request_begin_write); + } else { + hs_request_begin_read(request); + } + // ================ added by xiao ================ // + if (request) { + hs_request_terminate_connection(request); // 此处应该释放内存 + } + // ================ added by xiao end ================ // + } +} +``` +6. \ No newline at end of file diff --git a/utils/FxHttpServer/include/FxHttpServer.h b/utils/FxHttpServer/include/FxHttpServer.h index a3ecb011..00a9c178 100644 --- a/utils/FxHttpServer/include/FxHttpServer.h +++ b/utils/FxHttpServer/include/FxHttpServer.h @@ -21,6 +21,7 @@ extern "C" { typedef void (*ResponseHandle)(const char *, void *); typedef void (*HttpHandleCallback)(const char *, const unsigned int, ResponseHandle, void *); StatusCode FxHttpServerInit(HttpHandleCallback httpHandle); +StatusCode FxHttpServerExit(void); StatusCode FxHttpServerUnInit(void); #ifdef __cplusplus } diff --git a/utils/FxHttpServer/src/FxHttpServer.c b/utils/FxHttpServer/src/FxHttpServer.c index d083bd72..d68cb577 100644 --- a/utils/FxHttpServer/src/FxHttpServer.c +++ b/utils/FxHttpServer/src/FxHttpServer.c @@ -16,6 +16,7 @@ #include "ILog.h" #include "httpserver.h" #include +extern int gHttpServerRuning; static struct http_server_s *server = NULL; static struct http_server_s *poll_server = NULL; static HttpHandleCallback gHttpHandle = NULL; @@ -49,6 +50,11 @@ StatusCode FxHttpServerInit(HttpHandleCallback httpHandle) http_server_listen(server); return CreateStatusCode(STATUS_CODE_OK); } +StatusCode FxHttpServerExit(void) +{ + gHttpServerRuning = 0; + return CreateStatusCode(STATUS_CODE_OK); +} StatusCode FxHttpServerUnInit(void) { free(server);