Merge pull request #300 from Mikachu2333/fix/free_hwnd

处理 `xy.h` 内存以及部分资源未释放的问题
This commit is contained in:
曾奥然 2025-10-28 13:10:03 +08:00 committed by GitHub
commit 6060b325be
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 100 additions and 50 deletions

143
lib/xy.h
View File

@ -23,7 +23,7 @@
#ifndef XY_H #ifndef XY_H
#define XY_H #define XY_H
#define _XY_Version "v0.2.1.0-2025/10/06" #define _XY_Version "v0.2.1.1-2025/10/07"
#define _XY_Maintain_URL "https://github.com/RubyMetric/chsrc/blob/dev/lib/xy.h" #define _XY_Maintain_URL "https://github.com/RubyMetric/chsrc/blob/dev/lib/xy.h"
#define _XY_Maintain_URL2 "https://gitee.com/RubyMetric/chsrc/blob/dev/lib/xy.h" #define _XY_Maintain_URL2 "https://gitee.com/RubyMetric/chsrc/blob/dev/lib/xy.h"
@ -217,6 +217,27 @@ xy_malloc0 (size_t size)
* String * String
******************************************************/ ******************************************************/
/**
* @brief
*
* @param old_ptr (char **)
* @param new_str
*/
static inline void
xy_ptr_replace (char **old_ptr, char *new_str)
{
if (old_ptr && *old_ptr)
{
char *temp = *old_ptr;
*old_ptr = new_str;
free (temp);
}
else if (old_ptr)
{
*old_ptr = new_str;
}
}
/** /**
* @brief str pat replace * @brief str pat replace
* *
@ -479,15 +500,15 @@ xy_streql (const char *str1, const char *str2)
} }
static bool static bool
xy_streql_ic(const char *str1, const char *str2) xy_streql_ic (const char *str1, const char *str2)
{ {
if (NULL == str1 || NULL == str2) if (NULL == str1 || NULL == str2)
{ {
return false; return false;
} }
size_t len1 = strlen(str1); size_t len1 = strlen (str1);
size_t len2 = strlen(str2); size_t len2 = strlen (str2);
if (len1 != len2) if (len1 != len2)
{ {
return false; return false;
@ -495,7 +516,7 @@ xy_streql_ic(const char *str1, const char *str2)
for (size_t i = 0; i < len1; i++) for (size_t i = 0; i < len1; i++)
{ {
if (tolower(str1[i]) != tolower(str2[i])) if (tolower (str1[i]) != tolower (str2[i]))
{ {
return false; return false;
} }
@ -569,14 +590,16 @@ xy_str_start_with (const char *str, const char *prefix)
static char * static char *
xy_str_delete_prefix (const char *str, const char *prefix) xy_str_delete_prefix (const char *str, const char *prefix)
{ {
char *new = xy_strdup (str);
bool yes = xy_str_start_with (str, prefix); bool yes = xy_str_start_with (str, prefix);
if (!yes) if (!yes)
return new; {
return xy_strdup (str);
size_t len = strlen (prefix); }
char *cur = new + len; else
return cur; {
size_t len = strlen (prefix);
return xy_strdup (str + len);
}
} }
/** /**
@ -603,23 +626,26 @@ xy_str_delete_suffix (const char *str, const char *suffix)
static char * static char *
xy_str_strip (const char *str) xy_str_strip (const char *str)
{ {
char *new = xy_strdup (str); if (!str)
xy_cant_be_null (str);
while (strchr ("\n\r\v\t\f ", new[0])) const char *start = str;
{ while (*start && strchr ("\n\r\v\t\f ", *start))
new += 1; start++;
}
size_t len = strlen (new); if ('\0' == *start)
return xy_strdup ("");
char *last = new + len - 1; const char *end = start + strlen (start) - 1;
while (end >= start && strchr ("\n\r\v\t\f ", *end))
end--;
while (strchr ("\n\r\v\t\f ", *last)) size_t len = (size_t) (end - start + 1);
{ char *ret = xy_malloc0 (len + 1);
*last = '\0'; memcpy (ret, start, len);
last -= 1; ret[len] = '\0';
} return ret;
return new;
} }
typedef struct typedef struct
@ -733,7 +759,7 @@ xy_file_read (const char *path)
buf[read_bytes] = '\0'; buf[read_bytes] = '\0';
char *formatted_str = xy_str_gsub (buf, "\r\n", "\n"); char *formatted_str = xy_str_gsub (buf, "\r\n", "\n");
formatted_str = xy_str_gsub (formatted_str, "\r", "\n"); xy_ptr_replace (&formatted_str, xy_str_gsub (formatted_str, "\r", "\n"));
free (buf); free (buf);
@ -1152,13 +1178,19 @@ _xy_win_powershellv5_profile ()
static bool static bool
xy_file_exist (const char *path) xy_file_exist (const char *path)
{ {
const char *new_path = path; char *expanded_path = NULL;
const char *check_path = path;
if (xy_str_start_with (path, "~")) if (xy_str_start_with (path, "~"))
{ {
new_path = xy_2strcat (xy_os_home, path + 1); expanded_path = xy_2strcat (xy_os_home, path + 1);
check_path = expanded_path;
} }
// 0 即 F_OK // 0 即 F_OK
return (0==access (new_path, 0)) ? true : false; bool result = (0 == access (check_path, 0)) ? true : false;
if (expanded_path) free (expanded_path);
return result;
} }
/** /**
@ -1168,12 +1200,14 @@ xy_file_exist (const char *path)
static bool static bool
xy_dir_exist (const char *path) xy_dir_exist (const char *path)
{ {
char *allocated_dir = NULL;
const char *dir = path; const char *dir = path;
if (xy.on_windows) if (xy.on_windows)
{ {
if (xy_str_start_with (path, "~")) if (xy_str_start_with (path, "~"))
{ {
dir = xy_2strcat (xy_os_home, path + 1); allocated_dir = xy_2strcat (xy_os_home, path + 1);
dir = allocated_dir;
} }
} }
@ -1183,29 +1217,32 @@ xy_dir_exist (const char *path)
// 也可以用 opendir() #include <dirent.h> // 也可以用 opendir() #include <dirent.h>
DWORD attr = GetFileAttributesA (dir); DWORD attr = GetFileAttributesA (dir);
bool result = false;
if (attr == INVALID_FILE_ATTRIBUTES) if (attr == INVALID_FILE_ATTRIBUTES)
{ {
// Q: 我们应该报错吗? // Q: 我们应该报错吗?
return false; result = false;
} }
else if (attr & FILE_ATTRIBUTE_DIRECTORY) else if (attr & FILE_ATTRIBUTE_DIRECTORY)
{ {
return true; result = true;
} }
else else
{ {
return false; result = false;
} }
if (allocated_dir) free (allocated_dir);
return result;
#endif #endif
} }
else else
{ {
int status = system (xy_2strcat ("test -d ", dir)); char *tmp_cmd = xy_2strcat ("test -d ", dir);
int status = system (tmp_cmd);
if (0==status) free (tmp_cmd);
return true; bool result = (0==status);
else if (allocated_dir) free (allocated_dir);
return false; return result;
} }
return false; return false;
@ -1228,13 +1265,17 @@ xy_normalize_path (const char *path)
if (xy_str_start_with (new, "~")) if (xy_str_start_with (new, "~"))
{ {
new = xy_2strcat (xy_os_home, xy_str_delete_prefix (new, "~")); char *tmp = xy_str_delete_prefix (new, "~");
char *joined = xy_2strcat (xy_os_home, tmp);
free (tmp);
xy_ptr_replace (&new, joined);
} }
if (xy.on_windows) if (xy.on_windows)
return xy_str_gsub (new, "/", "\\"); {
else xy_ptr_replace (&new, xy_str_gsub (new, "/", "\\"));
return new; }
return new;
} }
@ -1251,10 +1292,10 @@ xy_parent_dir (const char *path)
char *dir = xy_normalize_path (path); char *dir = xy_normalize_path (path);
/* 不管是否为Windows全部统一使用 / 作为路径分隔符,方便后续处理 */ /* 不管是否为Windows全部统一使用 / 作为路径分隔符,方便后续处理 */
dir = xy_str_gsub (dir, "\\", "/"); xy_ptr_replace (&dir, xy_str_gsub (dir, "\\", "/"));
if (xy_str_end_with (dir, "/")) if (xy_str_end_with (dir, "/"))
dir = xy_str_delete_suffix (dir, "/"); xy_ptr_replace (&dir, xy_str_delete_suffix (dir, "/"));
char *last = NULL; char *last = NULL;
@ -1268,9 +1309,10 @@ xy_parent_dir (const char *path)
/* Windows上重新使用 \ 作为路径分隔符 */ /* Windows上重新使用 \ 作为路径分隔符 */
if (xy.on_windows) if (xy.on_windows)
return xy_str_gsub (dir, "/", "\\"); {
else xy_ptr_replace (&dir, xy_str_gsub (dir, "/", "\\"));
return dir; }
return dir;
} }
@ -1297,7 +1339,7 @@ xy_detect_os ()
if (fp) if (fp)
{ {
char buf[256] = {0}; char buf[256] = {0};
fread (buf, 1, sizeof(buf) - 1, fp); fread (buf, 1, sizeof (buf) - 1, fp);
fclose (fp); fclose (fp);
if (strstr (buf, "Linux")) if (strstr (buf, "Linux"))
{ {
@ -1332,9 +1374,10 @@ xy_detect_os ()
fp = popen ("uname -s", "r"); fp = popen ("uname -s", "r");
if (!fp) if (!fp)
{ {
if (opendir ("/etc/rc.d")) DIR *bsd_dir = opendir ("/etc/rc.d");
if (bsd_dir)
{ {
closedir (d); closedir (bsd_dir);
xy.on_bsd = true; xy.on_bsd = true;
return; return;
} }

View File

@ -863,6 +863,9 @@ measure_speed_for_every_source (Source_t sources[], int size, double speed_recor
char *curl_result = measure_speed_for_url (url); char *curl_result = measure_speed_for_url (url);
double speed = parse_and_say_curl_result (curl_result); double speed = parse_and_say_curl_result (curl_result);
speed_records[i] = speed; speed_records[i] = speed;
/* 释放 url 内存 */
if (url) free (url);
} }
else else
{ {
@ -1519,6 +1522,7 @@ chsrc_run_as_bash_file (const char *script_content)
char *cmd = xy_2strcat ("bash ", tmpfile); char *cmd = xy_2strcat ("bash ", tmpfile);
chsrc_run (cmd, RunOpt_Dont_Abort_On_Failure); chsrc_run (cmd, RunOpt_Dont_Abort_On_Failure);
remove (tmpfile); remove (tmpfile);
free (tmpfile); /* 释放 tmpfile 路径内存 */
} }
@ -1539,6 +1543,7 @@ chsrc_run_as_sh_file (const char *script_content)
char *cmd = xy_2strcat ("sh ", tmpfile); char *cmd = xy_2strcat ("sh ", tmpfile);
chsrc_run (cmd, RunOpt_Dont_Abort_On_Failure); chsrc_run (cmd, RunOpt_Dont_Abort_On_Failure);
remove (tmpfile); remove (tmpfile);
free (tmpfile);
} }
@ -1558,6 +1563,7 @@ chsrc_run_as_pwsh_file (const char *script_content)
char *cmd = xy_2strcat ("pwsh ", tmpfile); char *cmd = xy_2strcat ("pwsh ", tmpfile);
chsrc_run (cmd, RunOpt_Dont_Abort_On_Failure); chsrc_run (cmd, RunOpt_Dont_Abort_On_Failure);
remove (tmpfile); remove (tmpfile);
free (tmpfile);
} }
@ -1849,6 +1855,7 @@ chsrc_overwrite_file (const char *str, const char *filename)
size_t ret = fwrite (str, len, 1, f); size_t ret = fwrite (str, len, 1, f);
if (ret != 1) if (ret != 1)
{ {
fclose (f);
char *msg = ENGLISH ? xy_2strcat ("Write failed to ", file) char *msg = ENGLISH ? xy_2strcat ("Write failed to ", file)
: xy_2strcat ("写入文件失败: ", file); : xy_2strcat ("写入文件失败: ", file);
chsrc_error2 (msg); chsrc_error2 (msg);