Skip to content

Commit 6060b32

Browse files
authored
Merge pull request #300 from Mikachu2333/fix/free_hwnd
处理 `xy.h` 内存以及部分资源未释放的问题
2 parents c6897bd + d84bdba commit 6060b32

File tree

2 files changed

+100
-50
lines changed

2 files changed

+100
-50
lines changed

lib/xy.h

Lines changed: 93 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#ifndef XY_H
2424
#define XY_H
2525

26-
#define _XY_Version "v0.2.1.0-2025/10/06"
26+
#define _XY_Version "v0.2.1.1-2025/10/07"
2727
#define _XY_Maintain_URL "https://github.com/RubyMetric/chsrc/blob/dev/lib/xy.h"
2828
#define _XY_Maintain_URL2 "https://gitee.com/RubyMetric/chsrc/blob/dev/lib/xy.h"
2929

@@ -217,6 +217,27 @@ xy_malloc0 (size_t size)
217217
* String
218218
******************************************************/
219219

220+
/**
221+
* @brief 替换字符串指针并自动释放旧内存
222+
*
223+
* @param old_ptr 指向要被替换的字符串指针的指针 (char **)
224+
* @param new_str 新的字符串指针
225+
*/
226+
static inline void
227+
xy_ptr_replace (char **old_ptr, char *new_str)
228+
{
229+
if (old_ptr && *old_ptr)
230+
{
231+
char *temp = *old_ptr;
232+
*old_ptr = new_str;
233+
free (temp);
234+
}
235+
else if (old_ptr)
236+
{
237+
*old_ptr = new_str;
238+
}
239+
}
240+
220241
/**
221242
* @brief 将 str 中所有的 pat 字符串替换成 replace,返回一个全新的字符串;也可用作删除、缩小、扩张
222243
*
@@ -479,23 +500,23 @@ xy_streql (const char *str1, const char *str2)
479500
}
480501

481502
static bool
482-
xy_streql_ic(const char *str1, const char *str2)
503+
xy_streql_ic (const char *str1, const char *str2)
483504
{
484505
if (NULL == str1 || NULL == str2)
485506
{
486507
return false;
487508
}
488509

489-
size_t len1 = strlen(str1);
490-
size_t len2 = strlen(str2);
510+
size_t len1 = strlen (str1);
511+
size_t len2 = strlen (str2);
491512
if (len1 != len2)
492513
{
493514
return false;
494515
}
495516

496517
for (size_t i = 0; i < len1; i++)
497518
{
498-
if (tolower(str1[i]) != tolower(str2[i]))
519+
if (tolower (str1[i]) != tolower (str2[i]))
499520
{
500521
return false;
501522
}
@@ -569,14 +590,16 @@ xy_str_start_with (const char *str, const char *prefix)
569590
static char *
570591
xy_str_delete_prefix (const char *str, const char *prefix)
571592
{
572-
char *new = xy_strdup (str);
573593
bool yes = xy_str_start_with (str, prefix);
574594
if (!yes)
575-
return new;
576-
577-
size_t len = strlen (prefix);
578-
char *cur = new + len;
579-
return cur;
595+
{
596+
return xy_strdup (str);
597+
}
598+
else
599+
{
600+
size_t len = strlen (prefix);
601+
return xy_strdup (str + len);
602+
}
580603
}
581604

582605
/**
@@ -603,23 +626,26 @@ xy_str_delete_suffix (const char *str, const char *suffix)
603626
static char *
604627
xy_str_strip (const char *str)
605628
{
606-
char *new = xy_strdup (str);
629+
if (!str)
630+
xy_cant_be_null (str);
631+
607632

608-
while (strchr ("\n\r\v\t\f ", new[0]))
609-
{
610-
new += 1;
611-
}
633+
const char *start = str;
634+
while (*start && strchr ("\n\r\v\t\f ", *start))
635+
start++;
612636

613-
size_t len = strlen (new);
637+
if ('\0' == *start)
638+
return xy_strdup ("");
614639

615-
char *last = new + len - 1;
640+
const char *end = start + strlen (start) - 1;
641+
while (end >= start && strchr ("\n\r\v\t\f ", *end))
642+
end--;
616643

617-
while (strchr ("\n\r\v\t\f ", *last))
618-
{
619-
*last = '\0';
620-
last -= 1;
621-
}
622-
return new;
644+
size_t len = (size_t) (end - start + 1);
645+
char *ret = xy_malloc0 (len + 1);
646+
memcpy (ret, start, len);
647+
ret[len] = '\0';
648+
return ret;
623649
}
624650

625651
typedef struct
@@ -733,7 +759,7 @@ xy_file_read (const char *path)
733759
buf[read_bytes] = '\0';
734760

735761
char *formatted_str = xy_str_gsub (buf, "\r\n", "\n");
736-
formatted_str = xy_str_gsub (formatted_str, "\r", "\n");
762+
xy_ptr_replace (&formatted_str, xy_str_gsub (formatted_str, "\r", "\n"));
737763

738764
free (buf);
739765

@@ -1152,13 +1178,19 @@ _xy_win_powershellv5_profile ()
11521178
static bool
11531179
xy_file_exist (const char *path)
11541180
{
1155-
const char *new_path = path;
1181+
char *expanded_path = NULL;
1182+
const char *check_path = path;
1183+
11561184
if (xy_str_start_with (path, "~"))
11571185
{
1158-
new_path = xy_2strcat (xy_os_home, path + 1);
1186+
expanded_path = xy_2strcat (xy_os_home, path + 1);
1187+
check_path = expanded_path;
11591188
}
1189+
11601190
// 0 即 F_OK
1161-
return (0==access (new_path, 0)) ? true : false;
1191+
bool result = (0 == access (check_path, 0)) ? true : false;
1192+
if (expanded_path) free (expanded_path);
1193+
return result;
11621194
}
11631195

11641196
/**
@@ -1168,12 +1200,14 @@ xy_file_exist (const char *path)
11681200
static bool
11691201
xy_dir_exist (const char *path)
11701202
{
1203+
char *allocated_dir = NULL;
11711204
const char *dir = path;
11721205
if (xy.on_windows)
11731206
{
11741207
if (xy_str_start_with (path, "~"))
11751208
{
1176-
dir = xy_2strcat (xy_os_home, path + 1);
1209+
allocated_dir = xy_2strcat (xy_os_home, path + 1);
1210+
dir = allocated_dir;
11771211
}
11781212
}
11791213

@@ -1183,29 +1217,32 @@ xy_dir_exist (const char *path)
11831217
// 也可以用 opendir() #include <dirent.h>
11841218
DWORD attr = GetFileAttributesA (dir);
11851219

1220+
bool result = false;
11861221
if (attr == INVALID_FILE_ATTRIBUTES)
11871222
{
11881223
// Q: 我们应该报错吗?
1189-
return false;
1224+
result = false;
11901225
}
11911226
else if (attr & FILE_ATTRIBUTE_DIRECTORY)
11921227
{
1193-
return true;
1228+
result = true;
11941229
}
11951230
else
11961231
{
1197-
return false;
1232+
result = false;
11981233
}
1234+
if (allocated_dir) free (allocated_dir);
1235+
return result;
11991236
#endif
12001237
}
12011238
else
12021239
{
1203-
int status = system (xy_2strcat ("test -d ", dir));
1204-
1205-
if (0==status)
1206-
return true;
1207-
else
1208-
return false;
1240+
char *tmp_cmd = xy_2strcat ("test -d ", dir);
1241+
int status = system (tmp_cmd);
1242+
free (tmp_cmd);
1243+
bool result = (0==status);
1244+
if (allocated_dir) free (allocated_dir);
1245+
return result;
12091246
}
12101247

12111248
return false;
@@ -1228,13 +1265,17 @@ xy_normalize_path (const char *path)
12281265

12291266
if (xy_str_start_with (new, "~"))
12301267
{
1231-
new = xy_2strcat (xy_os_home, xy_str_delete_prefix (new, "~"));
1268+
char *tmp = xy_str_delete_prefix (new, "~");
1269+
char *joined = xy_2strcat (xy_os_home, tmp);
1270+
free (tmp);
1271+
xy_ptr_replace (&new, joined);
12321272
}
12331273

12341274
if (xy.on_windows)
1235-
return xy_str_gsub (new, "/", "\\");
1236-
else
1237-
return new;
1275+
{
1276+
xy_ptr_replace (&new, xy_str_gsub (new, "/", "\\"));
1277+
}
1278+
return new;
12381279
}
12391280

12401281

@@ -1251,10 +1292,10 @@ xy_parent_dir (const char *path)
12511292
char *dir = xy_normalize_path (path);
12521293

12531294
/* 不管是否为Windows,全部统一使用 / 作为路径分隔符,方便后续处理 */
1254-
dir = xy_str_gsub (dir, "\\", "/");
1295+
xy_ptr_replace (&dir, xy_str_gsub (dir, "\\", "/"));
12551296

12561297
if (xy_str_end_with (dir, "/"))
1257-
dir = xy_str_delete_suffix (dir, "/");
1298+
xy_ptr_replace (&dir, xy_str_delete_suffix (dir, "/"));
12581299

12591300
char *last = NULL;
12601301

@@ -1268,9 +1309,10 @@ xy_parent_dir (const char *path)
12681309

12691310
/* Windows上重新使用 \ 作为路径分隔符 */
12701311
if (xy.on_windows)
1271-
return xy_str_gsub (dir, "/", "\\");
1272-
else
1273-
return dir;
1312+
{
1313+
xy_ptr_replace (&dir, xy_str_gsub (dir, "/", "\\"));
1314+
}
1315+
return dir;
12741316
}
12751317

12761318

@@ -1297,7 +1339,7 @@ xy_detect_os ()
12971339
if (fp)
12981340
{
12991341
char buf[256] = {0};
1300-
fread (buf, 1, sizeof(buf) - 1, fp);
1342+
fread (buf, 1, sizeof (buf) - 1, fp);
13011343
fclose (fp);
13021344
if (strstr (buf, "Linux"))
13031345
{
@@ -1332,9 +1374,10 @@ xy_detect_os ()
13321374
fp = popen ("uname -s", "r");
13331375
if (!fp)
13341376
{
1335-
if (opendir ("/etc/rc.d"))
1377+
DIR *bsd_dir = opendir ("/etc/rc.d");
1378+
if (bsd_dir)
13361379
{
1337-
closedir (d);
1380+
closedir (bsd_dir);
13381381
xy.on_bsd = true;
13391382
return;
13401383
}

src/framework/core.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -863,6 +863,9 @@ measure_speed_for_every_source (Source_t sources[], int size, double speed_recor
863863
char *curl_result = measure_speed_for_url (url);
864864
double speed = parse_and_say_curl_result (curl_result);
865865
speed_records[i] = speed;
866+
867+
/* 释放 url 内存 */
868+
if (url) free (url);
866869
}
867870
else
868871
{
@@ -1519,6 +1522,7 @@ chsrc_run_as_bash_file (const char *script_content)
15191522
char *cmd = xy_2strcat ("bash ", tmpfile);
15201523
chsrc_run (cmd, RunOpt_Dont_Abort_On_Failure);
15211524
remove (tmpfile);
1525+
free (tmpfile); /* 释放 tmpfile 路径内存 */
15221526
}
15231527

15241528

@@ -1539,6 +1543,7 @@ chsrc_run_as_sh_file (const char *script_content)
15391543
char *cmd = xy_2strcat ("sh ", tmpfile);
15401544
chsrc_run (cmd, RunOpt_Dont_Abort_On_Failure);
15411545
remove (tmpfile);
1546+
free (tmpfile);
15421547
}
15431548

15441549

@@ -1558,6 +1563,7 @@ chsrc_run_as_pwsh_file (const char *script_content)
15581563
char *cmd = xy_2strcat ("pwsh ", tmpfile);
15591564
chsrc_run (cmd, RunOpt_Dont_Abort_On_Failure);
15601565
remove (tmpfile);
1566+
free (tmpfile);
15611567
}
15621568

15631569

@@ -1849,6 +1855,7 @@ chsrc_overwrite_file (const char *str, const char *filename)
18491855
size_t ret = fwrite (str, len, 1, f);
18501856
if (ret != 1)
18511857
{
1858+
fclose (f);
18521859
char *msg = ENGLISH ? xy_2strcat ("Write failed to ", file)
18531860
: xy_2strcat ("写入文件失败: ", file);
18541861
chsrc_error2 (msg);

0 commit comments

Comments
 (0)