From dcf12568867663796808818dc7836ab8be4971f1 Mon Sep 17 00:00:00 2001 From: 3405691582 Date: Sat, 22 Nov 2025 10:05:20 -0500 Subject: [PATCH] Ensure strsep operates on a copy of PATH. strsep modifies its first argument, which means that if we don't make a copy, any PATH processing that may occur after _CFProcessPath executes breaks because strsep will effectively change PATH to be only the first list item. For example, swiftpm's tool finding fails because it searches PATH, and if the tool in question doesn't reside in the first PATH item, things break. This only occurs on BSD and only when the program name, i.e., argv[0], is not an absolute path. --- Sources/CoreFoundation/CFPlatform.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Sources/CoreFoundation/CFPlatform.c b/Sources/CoreFoundation/CFPlatform.c index 8112cec632..e460134e96 100644 --- a/Sources/CoreFoundation/CFPlatform.c +++ b/Sources/CoreFoundation/CFPlatform.c @@ -266,10 +266,12 @@ const char *_CFProcessPath(void) { } // Search PATH. - if (argv0) { - char *paths = getenv("PATH"); + char *path = getenv("PATH"); + if (argv0 && path) { + char *paths = strdup(path); + char *remaining = paths; char *p = NULL; - while ((p = strsep(&paths, ":")) != NULL) { + while ((p = strsep(&remaining, ":")) != NULL) { char pp[PATH_MAX]; int l = snprintf(pp, PATH_MAX, "%s/%s", p, argv0); if (l >= PATH_MAX) { @@ -283,11 +285,13 @@ const char *_CFProcessPath(void) { _CFSetProgramNameFromPath(res); free(argv0); free(res); + free(paths); return __CFProcessPath; } free(res); } free(argv0); + free(paths); } // See if the shell will help.