From: Joe Souza <jsouza(a)yahoo.com> --- programs/cmd/wcmdmain.c | 43 ++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index fbec86a481a..996d438164d 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -193,12 +193,25 @@ static void find_insert_pos(const WCHAR *inputBuffer, int len, SEARCH_CONTEXT *s /* Handle paths here. Find last '\\' or other delimiter. * If not found then insert pos is the same as search pos. */ - while (cc > sc->search_pos && !wcschr(INTRA_PATH_DELIMS, inputBuffer[cc])) { - cc--; - } + if (sc->user_specified_quotes) { + /* If the user specified quotes then treat the usual delimiters as literals + * and ignore them. + */ + while (cc > sc->search_pos && inputBuffer[cc] != L'\\') { + cc--; + } - if (inputBuffer[cc] == L'\"' || wcschr(INTRA_PATH_DELIMS, inputBuffer[cc])) { - cc++; + if (inputBuffer[cc] == L'\"' || inputBuffer[cc] == L'\\') { + cc++; + } + } else { + while (cc > sc->search_pos && !wcschr(INTRA_PATH_DELIMS, inputBuffer[cc])) { + cc--; + } + + if (inputBuffer[cc] == L'\"' || wcschr(INTRA_PATH_DELIMS, inputBuffer[cc])) { + cc++; + } } sc->insert_pos = cc; @@ -257,6 +270,18 @@ static void get_next_matching_directory_entry(SEARCH_CONTEXT *sc, BOOL reverse) } } +static BOOL has_delimiters(WCHAR *path, const WCHAR *delims) +{ + BOOL ret = FALSE; + int cc = 0; + + while (path[cc] && !ret) { + ret = wcschr(delims, path[cc++]) ? TRUE : FALSE; + } + + return ret; +} + static void update_input_buffer(WCHAR *inputBuffer, const DWORD inputBufferLength, SEARCH_CONTEXT *sc) { BOOL needQuotes = FALSE; @@ -266,19 +291,19 @@ static void update_input_buffer(WCHAR *inputBuffer, const DWORD inputBufferLengt /* We have found the insert position for the results. Terminate the string here. */ inputBuffer[sc->insert_pos] = L'\0'; - /* If there are no spaces in the path then we can remove quotes when appending + /* If there are no spaces or delimiters in the path then we can remove quotes when appending * the search result, unless the search result itself requires them. */ - if (sc->have_quotes && !sc->user_specified_quotes && !wcschr(&inputBuffer[sc->search_pos], L' ')) { + if (sc->have_quotes && !sc->user_specified_quotes && !has_delimiters(&inputBuffer[sc->search_pos], PATH_SEPARATION_DELIMS)) { TRACE("removeQuotes = TRUE\n"); removeQuotes = TRUE; } /* Online documentation states that paths or filenames should be quoted if they are long * file names or contain spaces. In practice, modern Windows seems to quote paths/files - * only if they contain spaces. + * only if they contain spaces or delimiters. */ - needQuotes = wcschr(sc->fd[sc->current_entry].cFileName, L' ') ? TRUE : FALSE; + needQuotes = has_delimiters(sc->fd[sc->current_entry].cFileName, PATH_SEPARATION_DELIMS); len = lstrlenW(inputBuffer); /* Remove starting quotes, if able. */ if (removeQuotes && !needQuotes) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8573