git: 151ae090159e - stable/14 - realpath: Improve prev_len logic
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 25 Mar 2026 00:47:48 UTC
The branch stable/14 has been updated by des:
URL: https://cgit.FreeBSD.org/src/commit/?id=151ae090159eb2c179926de84cf2fc40d687d2cf
commit 151ae090159eb2c179926de84cf2fc40d687d2cf
Author: Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2026-03-19 01:26:16 +0000
Commit: Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2026-03-25 00:47:45 +0000
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
(cherry picked from commit 99d295e471bc362a7927047c89472e1ee2d0da6b)
---
lib/libc/stdlib/realpath.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/lib/libc/stdlib/realpath.c b/lib/libc/stdlib/realpath.c
index f23a3fd8c58e..8fcdd443d2b8 100644
--- a/lib/libc/stdlib/realpath.c
+++ b/lib/libc/stdlib/realpath.c
@@ -105,7 +105,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;
@@ -136,7 +135,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);
@@ -148,8 +149,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)) {