Skip to content

Commit 41556d3

Browse files
committed
common/common.c: revise getfullpath() for WIN32 builds [networkupstools#3065]
Started from review of PR networkupstools#3065 for issue networkupstools#3063. * The method had a potential NULL dereference * Only backslashes were considered * Issues above should never happen with real Windows API, but who knows what we get in cross-builds?.. Signed-off-by: Jim Klimov <[email protected]>
1 parent 009fbbd commit 41556d3

File tree

1 file changed

+40
-8
lines changed

1 file changed

+40
-8
lines changed

common/common.c

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,21 +1569,53 @@ int checkprocname(pid_t pid, const char *progname)
15691569

15701570
#ifdef WIN32
15711571
/* In WIN32 all non binaries files (namely configuration and PID files)
1572-
are retrieved relative to the path of the binary itself.
1573-
So this function fill "dest" with the full path to "relative_path"
1574-
depending on the .exe path */
1572+
* are retrieved relative to the path of the binary itself.
1573+
*
1574+
* So this function fills "buf" with the full path to "relative_path",
1575+
* depending on the currently running "*.exe" path.
1576+
*
1577+
* Note that the last (back/fwd)slash before the binary program name
1578+
* is removed, so any relative path in a directory should start with
1579+
* a slash of its own (like "/../lib", "/etc") as opposed to adding a
1580+
* suffix to the current binary's location (arch-specific?)
1581+
*
1582+
* A copy of "buf" is returned, so the caller should free the string
1583+
* it gets (if not NULL).
1584+
*/
15751585
char * getfullpath(char * relative_path)
15761586
{
1577-
char buf[NUT_PATH_MAX + 1];
1578-
if ( GetModuleFileName(NULL, buf, sizeof(buf)) == 0 ) {
1587+
char buf[NUT_PATH_MAX + 1];
1588+
char *last_fwdslash, *last_backslash;
1589+
1590+
if (GetModuleFileName(NULL, buf, sizeof(buf)) == 0) {
15791591
return NULL;
15801592
}
15811593

15821594
/* remove trailing executable name and its preceeding slash */
1583-
char * last_slash = strrchr(buf, '\\');
1584-
*last_slash = '\0';
1595+
last_backslash = strrchr(buf, '\\');
1596+
last_fwdslash = strrchr(buf, '/');
1597+
1598+
if (last_backslash && last_fwdslash) {
1599+
if (last_backslash < last_fwdslash) {
1600+
*last_fwdslash = '\0';
1601+
} else {
1602+
*last_backslash = '\0';
1603+
}
1604+
} else {
1605+
/* FIXME: What if neither slash is found?
1606+
* What do we even have then (dir? prog?)
1607+
* Probably the real Windows API should not return an unusable
1608+
* path value here, but some portability emulators might?..
1609+
*/
1610+
if (!last_backslash && !last_fwdslash)
1611+
upslogx(LOG_ERR, "%s: got a bogus module name without slashes: %s",
1612+
__func__, NUT_STRARG(buf));
1613+
1614+
if (last_backslash) *last_backslash = '\0';
1615+
if (last_fwdslash) *last_fwdslash = '\0';
1616+
}
15851617

1586-
if( relative_path ) {
1618+
if (relative_path) {
15871619
strncat(buf, relative_path, sizeof(buf) - 1);
15881620
}
15891621

0 commit comments

Comments
 (0)