diff options
| author | Dag-Erling Smørgrav <des@FreeBSD.org> | 2026-03-19 01:26:16 +0000 |
|---|---|---|
| committer | Dag-Erling Smørgrav <des@FreeBSD.org> | 2026-03-19 01:26:34 +0000 |
| commit | 99d295e471bc362a7927047c89472e1ee2d0da6b (patch) | |
| tree | 9471cec2488fca2306f177afb4c3f7a359e8ebf2 | |
| parent | dad6e6fc1ea4b737e9f1661ebd30da5d551e3d4a (diff) | |
realpath: Improve prev_len logic
* Save prev_len after having checked for and appended a trailing slash,
not before. This requires us to back up if we end up returning a
partial result, but previously we would sometimes return a partial
result with a trailing slash and sometimes without.
* Replace strlcat() with a faster strlcpy() since we know exactly how
far into the buffer we are.
MFC after: 1 week
Sponsored by: Klara, Inc.
Reviewed by: kevans
Differential Revision: https://reviews.freebsd.org/D55914
| -rw-r--r-- | lib/libc/stdlib/realpath.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/lib/libc/stdlib/realpath.c b/lib/libc/stdlib/realpath.c index 18f29e95ee6b..9dc0cc4d3dd4 100644 --- a/lib/libc/stdlib/realpath.c +++ b/lib/libc/stdlib/realpath.c @@ -98,7 +98,6 @@ realpath1(const char *path, char *resolved) left_len = 0; } - prev_len = resolved_len; if (resolved[resolved_len - 1] != '/') { if (resolved_len + 1 >= PATH_MAX) { errno = ENAMETOOLONG; @@ -129,7 +128,9 @@ realpath1(const char *path, char *resolved) /* * Append the next path component and lstat() it. */ - resolved_len = strlcat(resolved, next_token, PATH_MAX); + prev_len = resolved_len; + resolved_len += strlcpy(resolved + prev_len, next_token, + PATH_MAX - prev_len); if (resolved_len >= PATH_MAX) { errno = ENAMETOOLONG; return (NULL); @@ -141,8 +142,11 @@ realpath1(const char *path, char *resolved) * directory is not a directory. Rewind the path * to correctly indicate where the error lies. */ - if (errno == EACCES || errno == ENOTDIR) + if (errno == EACCES || errno == ENOTDIR) { + if (prev_len > 1) + prev_len--; resolved[prev_len] = '\0'; + } return (NULL); } if (S_ISLNK(sb.st_mode)) { |
