fix(platform): correct filename buffer handling and prevent overflows

- Replace undefined 'len' variable references with 'name_len'
- Add explicit null terminators after memcpy operations
- Move name_len declaration to Windows-specific scope to eliminate unused variable warning on BSD
- Standardize string copy pattern across all platforms: strlen -> clamp -> memcpy -> null terminate
- Fix increment operator placement for clarity (i++ moved outside array indexing)
- Remove duplicate name_len declaration in platform_directory_watch_check

This ensures proper bounds checking and null termination for filenames
on both Windows and BSD systems, preventing potential buffer overflows
when handling long filenames (approaching STK_PATH_MAX).
This commit is contained in:
2026-02-01 02:38:45 +01:00
parent 1919287c39
commit 28dfc89b15
+39 -23
View File
@@ -286,8 +286,9 @@ void *platform_get_symbol(void *h, const char *s)
#endif
}
char (*platform_directory_init_scan(const char *dir_path, size_t *out_count))
[STK_PATH_MAX] {
char (*platform_directory_init_scan(const char *dir_path,
size_t *out_count))[STK_PATH_MAX]
{
size_t count = 0, i = 0, name_len;
char(*list)[STK_PATH_MAX] = NULL;
#ifdef _WIN32
@@ -326,10 +327,11 @@ char (*platform_directory_init_scan(const char *dir_path, size_t *out_count))
if (is_valid_module_file(fd.cFileName) && i < count) {
name_len = strlen(fd.cFileName);
if (name_len >= STK_PATH_MAX)
len = STK_PATH_MAX - 1;
name_len = STK_PATH_MAX - 1;
memcpy(list[i], fd.cFileName, name_len);
list[i++][len] = '\0';
list[i][name_len] = '\0';
i++;
}
} while (FindNextFileA(h, &fd));
@@ -489,12 +491,11 @@ void *platform_directory_watch_start(const char *path)
fd, path, IN_CLOSE_WRITE | IN_DELETE | IN_MOVED_TO | IN_MOVED_FROM);
return (void *)(long)fd;
#else
size_t name_len;
#ifdef _WIN32
WIN32_FIND_DATAA fd;
HANDLE h;
char s[STK_PATH_MAX_OS];
size_t count = 0, i = 0;
size_t count = 0, i = 0, name_len;
#else
DIR *d;
struct dirent *e;
@@ -545,10 +546,12 @@ void *platform_directory_watch_start(const char *path)
if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
is_valid_module_file(fd.cFileName) && i < count) {
name_len = strlen(fd.cFileName);
if (len >= STK_PATH_MAX)
len = STK_PATH_MAX - 1;
memcpy(ctx->snaps[i].filename, fd.cFileName, len);
ctx->snaps[i++].mtime = fd.ftLastWriteTime;
if (name_len >= STK_PATH_MAX)
name_len = STK_PATH_MAX - 1;
memcpy(ctx->snaps[i].filename, fd.cFileName, name_len);
ctx->snaps[i].filename[name_len] = '\0';
ctx->snaps[i].mtime = fd.ftLastWriteTime;
i++;
}
} while (FindNextFileA(h, &fd));
@@ -773,7 +776,7 @@ stk_module_event_t *platform_directory_watch_check(
WIN32_FIND_DATAA fd;
HANDLE h;
char s[STK_PATH_MAX_OS];
size_t count = 0, name_len;
size_t count = 0;
sprintf(s, "%s\\*", ctx->path);
h = FindFirstFileA(s, &fd);
@@ -805,12 +808,12 @@ stk_module_event_t *platform_directory_watch_check(
if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
is_valid_module_file(fd.cFileName) && new_count < count) {
name_len = strlen(fd.cFileName);
if (len >= STK_PATH_MAX)
len = STK_PATH_MAX - 1;
if (name_len >= STK_PATH_MAX)
name_len = STK_PATH_MAX - 1;
memcpy(new_snaps[new_count].filename, fd.cFileName,
len);
new_snaps[new_count].filename[len] = '\0';
name_len);
new_snaps[new_count].filename[name_len] = '\0';
new_snaps[new_count].mtime = fd.ftLastWriteTime;
new_count++;
}
@@ -904,9 +907,13 @@ build_diff:
&new_snaps[j].mtime) != 0) {
if (is_file_ready(ctx->path,
new_snaps[j].filename)) {
strncpy((*file_list)[ev_index],
new_snaps[j].filename,
STK_PATH_MAX - 1);
name_len =
strlen(new_snaps[j].filename);
if (name_len >= STK_PATH_MAX)
name_len = STK_PATH_MAX - 1;
memcpy((*file_list)[ev_index],
new_snaps[j].filename, name_len);
(*file_list)[ev_index][name_len] = '\0';
evs[ev_index++] = STK_MOD_RELOAD;
} else {
new_snaps[j].mtime =
@@ -920,10 +927,11 @@ build_diff:
name_len =
strlen(ctx->snaps[i].filename);
if (name_len >= STK_PATH_MAX)
len = STK_PATH_MAX;
name_len = STK_PATH_MAX - 1;
memcpy((*file_list)[ev_index],
ctx->snaps[i].filename,
name_len);
(*file_list)[ev_index][name_len] = '\0';
evs[ev_index++] = STK_MOD_RELOAD;
} else {
new_snaps[j].mtime =
@@ -935,8 +943,12 @@ build_diff:
}
if (!found) {
strncpy((*file_list)[ev_index], ctx->snaps[i].filename,
STK_PATH_MAX - 1);
name_len = strlen(ctx->snaps[i].filename);
if (name_len >= STK_PATH_MAX)
name_len = STK_PATH_MAX - 1;
memcpy((*file_list)[ev_index], ctx->snaps[i].filename,
name_len);
(*file_list)[ev_index][name_len] = '\0';
evs[ev_index++] = STK_MOD_UNLOAD;
}
}
@@ -952,8 +964,12 @@ build_diff:
}
if (!found) {
strncpy((*file_list)[ev_index], new_snaps[j].filename,
STK_PATH_MAX - 1);
name_len = strlen(new_snaps[j].filename);
if (name_len >= STK_PATH_MAX)
name_len = STK_PATH_MAX - 1;
memcpy((*file_list)[ev_index], new_snaps[j].filename,
name_len);
(*file_list)[ev_index][name_len] = '\0';
evs[ev_index++] = STK_MOD_LOAD;
}
}