Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 25 Mar 2026 00:47:48 +0000
From:      Dag-Erling=?utf-8?Q? Sm=C3=B8rg?=rav <des@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 151ae090159e - stable/14 - realpath: Improve prev_len logic
Message-ID:  <69c330b4.3cdf7.46076d22@gitrepo.freebsd.org>

index | next in thread | raw e-mail

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)) {


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69c330b4.3cdf7.46076d22>