From 4fae64bfb3f7422e5a5acbcc1d7e7db0a7031d62 Mon Sep 17 00:00:00 2001 From: Sadhyama Vengilat Date: Mon, 1 Dec 2025 16:20:02 +0530 Subject: [PATCH] Crash fix when mac is NULL and add retry with fallback mac --- src/webcfg_multipart.c | 80 ++++++++++++++++++++++----------- tests/test_multipart_unittest.c | 40 +++++++++++++++-- 2 files changed, 91 insertions(+), 29 deletions(-) diff --git a/src/webcfg_multipart.c b/src/webcfg_multipart.c index 52528241..7dbc32a1 100644 --- a/src/webcfg_multipart.c +++ b/src/webcfg_multipart.c @@ -266,6 +266,11 @@ WEBCFG_STATUS webcfg_http_request(char **configData, int r_count, int status, lo //Replace {mac} string from default init url with actual deviceMAC WebcfgDebug("replaceMacWord to actual device mac\n"); webConfigURL = replaceMacWord(configURL, c, get_deviceMAC()); + if(webConfigURL == NULL) + { + WebcfgError("replaceMacWord failed. Failed to set webConfigURL\n"); + return WEBCFG_FAILURE; + } //Check the url is having empty mac or actual devicemac checkValidURL(&webConfigURL); if(get_global_supplementarySync() == 0) @@ -2252,6 +2257,11 @@ WEBCFG_STATUS print_tmp_doc_list(size_t mp_count) void checkValidURL(char **s) { + if (!s || *s == NULL) + { + WebcfgError("webConfigURL is Empty or NULL\n"); + return; + } char modified_url[256] = {0}; int maxRetryTime = 31; int backoffRetryTime = 0; @@ -2271,10 +2281,10 @@ void checkValidURL(char **s) { while (1) { if (backoffRetryTime <= maxRetryTime) { - backoffRetryTime = (int)pow(2, c) - 1; + backoffRetryTime = (1 << c) - 1; } const char *mac = get_deviceMAC(); - if (mac != NULL && strncmp(mac, "000000000000", 12) != 0) + if (mac != NULL && mac[0] != '\0' && strncmp(mac, "000000000000", 12) != 0) { WebcfgDebug("Mac fetched is %s\n", mac); strncat(modified_url, mac, sizeof(modified_url) - strlen(modified_url) - 1); @@ -2305,7 +2315,7 @@ void checkValidURL(char **s) { // Validate if the MAC is correct for the box const char *mac = get_deviceMAC(); - if (mac != NULL && strncmp(mac, start, 12) != 0) + if (mac != NULL && mac[0] != '\0' && strncmp(mac, start, 12) != 0) { WebcfgError("MAC Address in URL does not match actual device MAC. Updating...\n"); strncpy(modified_url, *s, start - *s); @@ -2323,39 +2333,57 @@ void checkValidURL(char **s) { char *replaceMacWord(const char *s, const char *macW, const char *deviceMACW) { + if (!s || !macW) + { + WebcfgInfo("macW or configURL is NULL\n"); + return NULL; + } char *result = NULL; int i, cnt = 0; - if(deviceMACW != NULL) + // When device mac is NULL replace with a fallback mac + if (deviceMACW == NULL || deviceMACW[0] == '\0') + { + WebcfgInfo("Device mac is NULL or Empty. Setting fallback mac\n"); + deviceMACW = "000000000000"; + } + + int deviceMACWlen = strlen(deviceMACW); + int macWlen = strlen(macW); + + // Counting the number of times mac word occur in the string + for (i = 0; s[i] != '\0'; i++) { - int deviceMACWlen = strlen(deviceMACW); - int macWlen = strlen(macW); - // Counting the number of times mac word occur in the string - for (i = 0; s[i] != '\0'; i++) + if (strstr(&s[i], macW) == &s[i]) { - if (strstr(&s[i], macW) == &s[i]) - { - cnt++; - // Jumping to index after the mac word. - i += macWlen - 1; - } + cnt++; + // Jumping to index after the mac word. + i += macWlen - 1; } + } + + result = (char *)malloc(i + cnt * (deviceMACWlen - macWlen) + 1); + if(result == NULL) + { + WebcfgError("malloc failed for result\n"); + return NULL; + } - result = (char *)malloc(i + cnt * (deviceMACWlen - macWlen) + 1); - i = 0; - while (*s) + i = 0; + while (*s) + { + if (strstr(s, macW) == s) { - if (strstr(s, macW) == s) - { - strcpy(&result[i], deviceMACW); - i += deviceMACWlen; - s += macWlen; - } - else - result[i++] = *s++; + strcpy(&result[i], deviceMACW); + i += deviceMACWlen; + s += macWlen; + } + else + { + result[i++] = *s++; } - result[i] = '\0'; } + result[i] = '\0'; return result; } diff --git a/tests/test_multipart_unittest.c b/tests/test_multipart_unittest.c index ffc10698..943050b4 100644 --- a/tests/test_multipart_unittest.c +++ b/tests/test_multipart_unittest.c @@ -70,13 +70,13 @@ struct mock_token_data { struct mock_token_data mock_data; -char device_mac[32] = {'\0'}; +char *mock_device_mac = "b42xxxxxxxxx"; char* get_deviceMAC() { - char *device_mac = strdup("b42xxxxxxxxx"); - return device_mac; + return mock_device_mac; } + char * getRebootReason() { char *reason = strdup("factory-reset"); @@ -376,6 +376,22 @@ void test_replaceMac(){ CU_ASSERT_STRING_EQUAL(webConfigURL,"https://config/b42xxxxxxxxx/com"); } +void test_replaceMac_NullUrl(){ + char *configURL= NULL; + char c[] = "{sss}"; + char *webConfigURL = replaceMacWord(configURL, c, get_deviceMAC()); + CU_ASSERT_PTR_NULL(webConfigURL); +} + +void test_replaceMac_NullMac(){ + char *configURL= "https://config/{sss}/com"; + char c[] = "{sss}"; + mock_device_mac = NULL; + char *webConfigURL = replaceMacWord(configURL, c, get_deviceMAC()); + CU_ASSERT_STRING_EQUAL(webConfigURL,"https://config/000000000000/com"); + mock_device_mac = "b42xxxxxxxxx"; // Restore for other tests +} + void test_checkValidURL_ValidURL(){ char *webConfigURL = strdup("https://sample/device/b42xxxxxxxxx/config"); @@ -392,6 +408,20 @@ void test_checkValidURL_InvalidURL(){ CU_ASSERT_STRING_EQUAL(webConfigURL,expected_url); } +void test_checkValidURL_NullInput(){ + char *webConfigURL = NULL; + checkValidURL(&webConfigURL); + CU_ASSERT_PTR_NULL(webConfigURL); +} + +void test_checkValidURL_InvalidMac(){ + + char *webConfigURL = strdup("https://sample/device/c44xxxxxxxxx/config"); + checkValidURL(&webConfigURL); + const char *expected_url ="https://sample/device/b42xxxxxxxxx/config"; + CU_ASSERT_STRING_EQUAL(webConfigURL,expected_url); +} + void test_createHeader(){ @@ -1459,8 +1489,12 @@ void add_suites( CU_pSuite *suite ) *suite = CU_add_suite( "tests", NULL, NULL ); CU_add_test( *suite, "test generate_trans_uuid", test_generate_trans_uuid); CU_add_test( *suite, "test replaceMacWord", test_replaceMac); + CU_add_test( *suite, "test replaceMacWord_NullMac", test_replaceMac_NullMac); + CU_add_test( *suite, "test replaceMac_NullUrl", test_replaceMac_NullUrl); CU_add_test( *suite, "test checkValidURL_ValidURL", test_checkValidURL_ValidURL); CU_add_test( *suite, "test checkValidURL_InvalidURL", test_checkValidURL_InvalidURL); + CU_add_test( *suite, "test checkValidURL_NullInput", test_checkValidURL_NullInput); + CU_add_test( *suite, "test checkValidURL_InvalidMac", test_checkValidURL_InvalidMac); CU_add_test( *suite, "test createCurlHeader", test_createHeader); CU_add_test( *suite, "test createHeader_doc_header_max_data", test_createHeader_doc_header_max_data); CU_add_test( *suite, "test createHeader_primary_sync", test_createHeader_primary_sync);