git: 72bb9eb7b6de - main - pwd(1): De-obfuscate, style(9)

From: Olivier Certner <olce_at_FreeBSD.org>
Date: Wed, 23 Sep 2026 11:38:01 UTC
The branch main has been updated by olce:

URL: https://cgit.FreeBSD.org/src/commit/?id=72bb9eb7b6decc34f343bdcbf0a8df0c73f9edd4

commit 72bb9eb7b6decc34f343bdcbf0a8df0c73f9edd4
Author:     Olivier Certner <olce@FreeBSD.org>
AuthorDate: 2026-09-07 16:09:54 +0000
Commit:     Olivier Certner <olce@FreeBSD.org>
CommitDate: 2026-09-23 11:37:45 +0000

    pwd(1): De-obfuscate, style(9)
    
    In getcwd_logical(), test for a '.' or '..' component in one of the most
    straightforward and intelligible ways possible.
    
    In particular, this removes a superfluous re-test of the the component's
    first character being '.' when the first one did not pass and, more
    importantly, prevents the second test from relying on a side-effect in
    the first.
    
    While here, for better clarity, replace the loop that searches for '/'
    with a simple call to strchrnul().
    
    Add high-level comments about what is going on.
    
    While here, test explicitly that pointed 'char' values are not 0 ('\0')
    (style(9)).
    
    While here, separate the successive steps of getcwd_logical() with blank
    lines.
    
    No functional change (intended).
    
    Discussed with: emaste
    Fixes:          2df923c5d2d0 ("pwd: Clean up and adopt POSIX semantics")
    MFC after:      3 days
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D59709
---
 bin/pwd/pwd.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/bin/pwd/pwd.c b/bin/pwd/pwd.c
index 2bbf5457ec17..f619024fdcff 100644
--- a/bin/pwd/pwd.c
+++ b/bin/pwd/pwd.c
@@ -33,33 +33,40 @@
 #include <sys/param.h>
 #include <sys/stat.h>
 
+#include <assert.h>
 #include <err.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 
 static char *
 getcwd_logical(void)
 {
 	struct stat log, phy;
-	char *pwd, *p, *q;
+	char *pwd, *s, *e;
 
 	/* $PWD is set and absolute */
 	if ((pwd = getenv("PWD")) == NULL || *pwd != '/')
 		return (NULL);
+
 	/* $PWD does not contain /./ or /../ */
-	for (p = pwd; *p; p = q) {
-		for (q = ++p; *q && *q != '/'; q++)
-			/* nothing */;
-		if ((*p == '.' && q == ++p) ||
-		    (*p == '.' && q == ++p))
+	e = pwd;
+	do {
+		assert(*e == '/');
+		s = e + 1; /* Beginning of next component (may point to NUL). */
+		/* Search for the component's end. */
+		e = strchrnul(s, '/');
+		if (s[0] == '.' && (s + 1 == e || (s[1] == '.' && s + 2 == e)))
 			return (NULL);
-	}
+	} while (*e != '\0');
+
 	/* $PWD refers to the current directory */
 	if (stat(pwd, &log) != 0 || stat(".", &phy) != 0 ||
 	    log.st_dev != phy.st_dev || log.st_ino != phy.st_ino)
 		return (NULL);
+
 	return (pwd);
 }