From 93d7057293e32cb0c4781ba933a82341e10801de Mon Sep 17 00:00:00 2001 From: Francois Gouget <fgouget@psn.net> Date: Sun, 9 Jan 2000 21:34:34 +0000 Subject: [PATCH] DOSFS_DoGetFullPathName would underflow (p would get past the beginning of buffer) if given the name "//..". Regrouped the handling of the directory separators. Directory separators in the returned path are now alway a single "\" which simplifies the handling of ".." in the name. --- files/dos_fs.c | 56 ++++++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/files/dos_fs.c b/files/dos_fs.c index ac263750af9..64fbdb4e9ba 100644 --- a/files/dos_fs.c +++ b/files/dos_fs.c @@ -1058,28 +1058,24 @@ static DWORD DOSFS_DoGetFullPathName( LPCSTR name, DWORD len, LPSTR result, char *p; DWORD ret; - /* last possible position for a char != 0 */ - char *endchar = buffer + sizeof(buffer) - 2; - *endchar = '\0'; + /* Address of the last byte in the buffer */ + char *endbuf = buffer + sizeof(buffer) - 1; TRACE("converting '%s'\n", name ); if (!name || ((drive = DOSFS_GetPathDrive( &name )) == -1) ) - { SetLastError( ERROR_INVALID_PARAMETER ); + { + SetLastError( ERROR_INVALID_PARAMETER ); return 0; } p = buffer; *p++ = 'A' + drive; *p++ = ':'; - if (IS_END_OF_NAME(*name) && (*name)) /* Absolute path */ - { - while (((*name == '\\') || (*name == '/')) && (!*endchar) ) - *p++ = *name++; - } - else /* Relative path or empty path */ + *p++ = '\\'; + if ((*name!='/') && (*name!='\\')) { - *p++ = '\\'; + /* Relative path or empty path */ lstrcpynA( p, DRIVE_GetDosCwd(drive), sizeof(buffer) - 4 ); if ( *p ) { @@ -1087,41 +1083,47 @@ static DWORD DOSFS_DoGetFullPathName( LPCSTR name, DWORD len, LPSTR result, *p++ = '\\'; } } - *p = '\0'; while (*name) { + while ((*name == '\\') || (*name == '/')) + name++; if (*name == '.') { if (IS_END_OF_NAME(name[1])) { name++; - while ((*name == '\\') || (*name == '/')) name++; continue; } else if ((name[1] == '.') && IS_END_OF_NAME(name[2])) { - name += 2; - while ((*name == '\\') || (*name == '/')) name++; - - if (p < buffer + 3) /* no previous dir component */ - continue; - p--; /* skip previously added '\\' */ - while ((*p == '\\') || (*p == '/')) p--; + if (p == buffer + 3) { + /* no previous dir component */ + SetLastError( ERROR_PATH_NOT_FOUND ); + return 0; + } + /* skip previously added '\\' */ + p-=2; /* skip previous dir component */ - while ((*p != '\\') && (*p != '/')) p--; + while (*p != '\\') + p--; p++; + + name += 2; continue; } } - if ( *endchar ) - { SetLastError( ERROR_PATH_NOT_FOUND ); + while (!IS_END_OF_NAME(*name) && (p<endbuf) ) + *p++ = *name++; + if ((p<endbuf) && ((*name == '\\') || (*name == '/'))) { + *p++='\\'; + name++; + } + if ( p==endbuf && *name ) + { + SetLastError( ERROR_PATH_NOT_FOUND ); return 0; } - while (!IS_END_OF_NAME(*name) && (!*endchar) ) - *p++ = *name++; - while (((*name == '\\') || (*name == '/')) && (!*endchar) ) - *p++ = *name++; } *p = '\0'; -- GitLab