[PATCH v2 0/2] MR9946: start: Remove quotes from the path specified by '/d'.
I'm not sure how to write a test case for this bug, as it involves creating a child process and I don't know how to verify if the child process was created correctly. Please test manually: enter `start /d "c:\windows" regedit.exe` in a batch file. It won't work correctly because `start` wraps the directory specified by `/D` with `L"\"\\\""` and `L"\\\"\""`. -- v2: start: Remove quotes from the path specified by '/d'. cmd/tests: Add test for 'start' with '/d'. https://gitlab.winehq.org/wine/wine/-/merge_requests/9946
From: YeshunYe <yeyeshun@uniontech.com> Signed-off-by: YeshunYe <yeyeshun@uniontech.com> --- programs/cmd/tests/test_builtins.bat | 5 +++++ programs/cmd/tests/test_builtins.bat.exp | 1 + programs/cmd/tests/test_builtins.cmd | 5 +++++ programs/cmd/tests/test_builtins.cmd.exp | 1 + 4 files changed, 12 insertions(+) diff --git a/programs/cmd/tests/test_builtins.bat b/programs/cmd/tests/test_builtins.bat index 1bd3de55292..5f297430905 100644 --- a/programs/cmd/tests/test_builtins.bat +++ b/programs/cmd/tests/test_builtins.bat @@ -92,6 +92,11 @@ rem call :setError 666 & (start /B I\dont\exist.exe &&echo SUCCESS !errorlevel!| rem can't run this test, generates a nice popup under windows call :setError 666 & (start "" /B /WAIT cmd.exe /c "echo foo & exit /b 1024" &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) call :setError 666 & (start "" /B cmd.exe /c "(choice /C:YN /T:3 /D:Y > NUL) & exit /b 1024" &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +mkdir foo & cd foo +set "FOO_PATH=%cd%" > NUL +cd .. +call :setError 666 & (start /B /WAIT /d "%FOO_PATH%" cmd /s /c "if /I \"%%cd%%\"==\"%FOO_PATH%\" (exit 0) else (exit 1)" >nul &&echo !errorlevel!) +rd /q /s foo echo --- success/failure for TYPE command mkdir foo & cd foo echo a > fileA diff --git a/programs/cmd/tests/test_builtins.bat.exp b/programs/cmd/tests/test_builtins.bat.exp index 397b720c3bf..85ac8052802 100644 --- a/programs/cmd/tests/test_builtins.bat.exp +++ b/programs/cmd/tests/test_builtins.bat.exp @@ -62,6 +62,7 @@ FAILURE 255 foo@space@ SUCCESS 1024 @todo_wine@SUCCESS 666 +@todo_wine@0 --- success/failure for TYPE command FAILURE 1 SUCCESS 0 diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd index aa709f31850..9564168adf8 100644 --- a/programs/cmd/tests/test_builtins.cmd +++ b/programs/cmd/tests/test_builtins.cmd @@ -675,6 +675,11 @@ rem call :setError 666 & (start /B I\dont\exist.exe &&echo SUCCESS !errorlevel!| rem can't run this test, generates a nice popup under windows call :setError 666 & (start "" /B /WAIT cmd.exe /c "echo foo & exit /b 1024" &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) call :setError 666 & (start "" /B cmd.exe /c "(choice /C:YN /T:3 /D:Y > NUL) & exit /b 1024" &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +mkdir foo & cd foo +set "FOO_PATH=%cd%" > NUL +cd .. +call :setError 666 & (start /B /WAIT /d "%FOO_PATH%" cmd /s /c "if /I \"%%cd%%\"==\"%FOO_PATH%\" (exit 0) else (exit 1)" >nul &&echo !errorlevel!) +rd /q /s foo echo --- success/failure for TYPE command mkdir foo & cd foo echo a > fileA diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index dbbfbba27fb..53143ea9b7f 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -581,6 +581,7 @@ FAILURE 255 foo@space@ SUCCESS 1024 @todo_wine@SUCCESS 666 +@todo_wine@0 --- success/failure for TYPE command FAILURE 1 SUCCESS 0 -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9946
From: YeshunYe <yeyeshun@uniontech.com> Signed-off-by: YeshunYe <yeyeshun@uniontech.com> --- programs/cmd/tests/test_builtins.bat.exp | 2 +- programs/cmd/tests/test_builtins.cmd.exp | 2 +- programs/start/start.c | 12 ++++++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/programs/cmd/tests/test_builtins.bat.exp b/programs/cmd/tests/test_builtins.bat.exp index 85ac8052802..1a7492ccc2b 100644 --- a/programs/cmd/tests/test_builtins.bat.exp +++ b/programs/cmd/tests/test_builtins.bat.exp @@ -62,7 +62,7 @@ FAILURE 255 foo@space@ SUCCESS 1024 @todo_wine@SUCCESS 666 -@todo_wine@0 +0 --- success/failure for TYPE command FAILURE 1 SUCCESS 0 diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index 53143ea9b7f..7899d48d507 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -581,7 +581,7 @@ FAILURE 255 foo@space@ SUCCESS 1024 @todo_wine@SUCCESS 666 -@todo_wine@0 +0 --- success/failure for TYPE command FAILURE 1 SUCCESS 0 diff --git a/programs/start/start.c b/programs/start/start.c index 80f623e4c66..8840d4ab042 100644 --- a/programs/start/start.c +++ b/programs/start/start.c @@ -458,6 +458,18 @@ static void parse_command_line( int argc, WCHAR *argv[] ) usage(); } else opts.sei.lpDirectory = argv[++i]; + + if (opts.sei.lpDirectory[0] == '\"') + { + int len = wcslen(opts.sei.lpDirectory); + /* no need to free since the process will exit shortly */ + WCHAR* lpDirectory = wcsdup(opts.sei.lpDirectory); + if (lpDirectory[len - 1] == '\"') + lpDirectory[len - 1] = 0; + else + WINE_ERR("quotes does not match!\n"); + opts.sei.lpDirectory = lpDirectory + 1; + } } else if (is_option(argv[i], L"/b")) opts.creation_flags &= ~CREATE_NEW_CONSOLE; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9946
On Tue Jan 27 03:36:24 2026 +0000, eric pouech wrote:
a test should be needed for testing, you could try to use (not fully tested): start /B /WAIT /d "foo" cmd /s /c "if /I "%cd%"=="foo" (exit 0) else (exit 1)" (replace foo by a path that exists) and check command return status (it should 0 upon success, and 1 if failure) done.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/9946#note_128084
eric pouech (@epo) commented about programs/start/start.c:
usage(); } else opts.sei.lpDirectory = argv[++i]; + + if (opts.sei.lpDirectory[0] == '\"') + { + int len = wcslen(opts.sei.lpDirectory); + /* no need to free since the process will exit shortly */ + WCHAR* lpDirectory = wcsdup(opts.sei.lpDirectory); + if (lpDirectory[len - 1] == '\"') + lpDirectory[len - 1] = 0; + else + WINE_ERR("quotes does not match!\n");
that should be a proper error message not a WINE\_\* message (and probably setting start.exe exit code) note: native start.exe prints an error message if the directory passed in /d isn't a valid one... and the same as the one I get when there's no trailing " so probably, the simplest solution is to remove quotes when leading & trailing are present, and fail if resulting directory doesn't exist -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9946#note_128105
eric pouech (@epo) commented about programs/start/start.c:
usage(); } else opts.sei.lpDirectory = argv[++i]; + + if (opts.sei.lpDirectory[0] == '\"') + { + int len = wcslen(opts.sei.lpDirectory); + /* no need to free since the process will exit shortly */ + WCHAR* lpDirectory = wcsdup(opts.sei.lpDirectory); + if (lpDirectory[len - 1] == '\"')
you should test that len is not zero before accessing \[len - 1\] -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9946#note_128104
This merge request was approved by eric pouech. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9946
participants (3)
-
eric pouech (@epo) -
Yeshun Ye (@yeyeshun) -
YeshunYe