commit e0353bf7735fbe23288e9196d6a3a45cea4d051e
parent 2fc9aecde3281b81799ed4c776d249af6c3941e2
Author: Chris Bracken <chris@bracken.jp>
Date: Mon, 15 Dec 2025 09:58:55 +0900
Use dynamic buffer allocation for paths
The POSIX standard notes that if PATH_MAX is not defined in <limits.h>,
it's because the system does not have a fixed, predetermined limit for
the length of a pathname. Some modern systems, intentionally do not
define PATH_MAX to discourage its use. Developers are instead expected
to query the limit for a specific path at runtime using
`pathconf(path, _PC_PATH_MAX)`.
The Rationale section of the standard, which contains explanatory notes,
explicitly warns developers against using PATH_MAX to allocate buffers.
From IEEE Std 1003.1, 2004 Edition:
> "Many historical implementations have a fixed value for PATH_MAX.
> These implementations suffer from an inability to take advantage of
> file systems that do not have this limit. ... Applications should not
> assume that the value of PATH_MAX is a fixed value on a given system."
Diffstat:
2 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/git/repo.c b/git/repo.c
@@ -188,13 +188,14 @@ char* format_filemode(git_filemode_t m) {
}
char* gitrepo_name_from_path(const char* repo_path) {
- char path[PATH_MAX];
- estrlcpy(path, repo_path, sizeof(path));
- const char* filename = basename(path);
+ char* path_copy = estrdup(repo_path);
+ const char* filename = basename(path_copy);
if (!filename) {
err(1, "basename");
}
- return estrdup(filename);
+ char* result = estrdup(filename);
+ free(path_copy);
+ return result;
}
char* gitrepo_shortname_from_name(const char* name) {
diff --git a/utils.c b/utils.c
@@ -32,8 +32,7 @@ char* path_concat(char* out, size_t out_len, const char* p1, const char* p2) {
}
int mkdirp(const char* path) {
- char mut_path[PATH_MAX];
- estrlcpy(mut_path, path, sizeof(mut_path));
+ char* mut_path = estrdup(path);
for (char* p = mut_path + (mut_path[0] == '/'); *p; p++) {
if (*p != '/') {
@@ -41,13 +40,17 @@ int mkdirp(const char* path) {
}
*p = '\0';
if (mkdir(mut_path, S_IRWXU | S_IRWXG | S_IRWXO) < 0 && errno != EEXIST) {
+ free(mut_path);
return -1;
}
*p = '/';
}
if (mkdir(mut_path, S_IRWXU | S_IRWXG | S_IRWXO) < 0 && errno != EEXIST) {
+ free(mut_path);
return -1;
}
+
+ free(mut_path);
return 0;
}