From 075894bc4485d35712d0164b4c73403ba39e3016 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Wed, 17 Jul 2024 08:38:33 +0900 Subject: [PATCH] [CMD] Fix GetPathCase function (#7113) This GetPathCase function does resolve the path with wildcard pattern, and fix the alphabet cases, by using kernel32!FindFirstFile function. Enable wildcard at the middle of the file path in cmd.exe by fixing this function. JIRA issue: CORE-6609 JIRA issue: CORE-13906 - Fix GetPathCase function for supporting wildcard at the - middle of the file path. - Make GetPathCase string-safe. - Optimize GetPathCase. --- base/shell/cmd/cmd.h | 2 +- base/shell/cmd/misc.c | 48 ++++++++++++++++++++++++++++--------------- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/base/shell/cmd/cmd.h b/base/shell/cmd/cmd.h index d07f98301ea..8b486b05619 100644 --- a/base/shell/cmd/cmd.h +++ b/base/shell/cmd/cmd.h @@ -325,7 +325,7 @@ VOID StripQuotes(LPTSTR); BOOL IsValidPathName(IN LPCTSTR pszPath); BOOL IsExistingFile(IN LPCTSTR pszPath); BOOL IsExistingDirectory(IN LPCTSTR pszPath); -VOID GetPathCase(TCHAR *, TCHAR *); +VOID GetPathCase(IN LPCTSTR Path, OUT LPTSTR OutPath); #define PROMPT_NO 0 #define PROMPT_YES 1 diff --git a/base/shell/cmd/misc.c b/base/shell/cmd/misc.c index 13403f9f2d0..1386cf57e93 100644 --- a/base/shell/cmd/misc.c +++ b/base/shell/cmd/misc.c @@ -83,45 +83,59 @@ cgetchar (VOID) /* * Takes a path in and returns it with the correct case of the letters */ -VOID GetPathCase( TCHAR * Path, TCHAR * OutPath) +VOID GetPathCase(IN LPCTSTR Path, OUT LPTSTR OutPath) { - UINT i = 0; + SIZE_T i; + SIZE_T cchPath = _tcslen(Path); TCHAR TempPath[MAX_PATH]; + LPTSTR pchTemp = TempPath; + LPTSTR pchTempEnd = TempPath + _countof(TempPath); WIN32_FIND_DATA FindFileData; HANDLE hFind; - _tcscpy(TempPath, _T("")); - _tcscpy(OutPath, _T("")); - for(i = 0; i < _tcslen(Path); i++) + *pchTemp = OutPath[0] = 0; + + for (i = 0; i < cchPath; ++i) { - if (Path[i] != _T('\\')) + if (pchTemp + 1 >= pchTempEnd) { - _tcsncat(TempPath, &Path[i], 1); - if (i != _tcslen(Path) - 1) + // On failure, copy the original path for an error message + StringCchCopy(OutPath, MAX_PATH, Path); + return; + } + + if (Path[i] != _T('\\') && Path[i] != _T('/')) + { + *pchTemp++ = Path[i]; + *pchTemp = 0; + if (i != cchPath - 1) continue; } + /* Handle the base part of the path different. Because if you put it into findfirstfile, it will return your current folder */ - if (_tcslen(TempPath) == 2 && TempPath[1] == _T(':')) + if (TempPath[0] && TempPath[1] == _T(':') && !TempPath[2]) /* "C:", "D:" etc. */ { - _tcscat(OutPath, TempPath); - _tcscat(OutPath, _T("\\")); - _tcscat(TempPath, _T("\\")); + StringCchCat(OutPath, MAX_PATH, TempPath); + StringCchCat(OutPath, MAX_PATH, _T("\\")); + StringCchCat(TempPath, _countof(TempPath), _T("\\")); } else { - hFind = FindFirstFile(TempPath,&FindFileData); + hFind = FindFirstFile(TempPath, &FindFileData); if (hFind == INVALID_HANDLE_VALUE) { - _tcscpy(OutPath, Path); + StringCchCopy(OutPath, MAX_PATH, Path); return; } - _tcscat(TempPath, _T("\\")); - _tcscat(OutPath, FindFileData.cFileName); - _tcscat(OutPath, _T("\\")); FindClose(hFind); + StringCchCat(OutPath, MAX_PATH, _T("\\")); + StringCchCat(OutPath, MAX_PATH, FindFileData.cFileName); + StringCchCat(OutPath, MAX_PATH, _T("\\")); + StringCchCopy(TempPath, _countof(TempPath), OutPath); } + pchTemp = TempPath + _tcslen(TempPath); } }