-
Notifications
You must be signed in to change notification settings - Fork 31
Fix a case-sensitive issue with ProcessUtil.pathOfCommand(Path path) on Windows #503
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
gsmet
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot. I added some context and a comment.
Also, I wonder if you would have time to add some tests for this specifically for Windows. We can add a Windows runner to our CI to make sure this is fully sorted out.
Note that I would make it another PR as I think we need this PR to be included ASAP as I would like to include the fix in 3.30.1, that I will ship next Wednesday.
process/src/main/java/io/smallrye/common/process/ProcessUtil.java
Outdated
Show resolved
Hide resolved
| for (Path segment : searchPath()) { | ||
| Path execPath = segment.resolve(path); | ||
| if (OS.current() == OS.WINDOWS) { | ||
| for (String ext : Windows.pathExt) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah so the thing is we have: PATHEXT=.COM;.EXE;.BAT;.CMD;.PS1 . Which means that we actually build a path with .EXE.
I wonder if we should lowercase the extensions in Windows but even so, it's probably safer to use toRealPath anyway, in case someone actually has an executable.EXE, which should work with a case insenstive FS.
@dmlloyd WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My only concerns would be the cost of toRealPath itself, and the security implications (for example, do we pass NOFOLLOW_LINKS to toRealPath? why or why not? and, what if the real path ends up being in a totally different directory?).
I think that if we do go the toRealPath route, then instead of returning the toRealPath we should just look at its filename part and make sure it matches (e.g. String#equalsIgnoreCase) the original, and if so, take the original path and resolveSibling the filename part of the result of toRealPath. That would probably be safest.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did a little experiment. I changed the file name of podman.exe to podman.EXE, then opened a new cmd and typed podman --version. I get the output: podman version 5.6.2. So I believe we can simulate Windows OS search behavior by just taking the lowercase of the extension, something like: Path execPathExt = execPath.getParent().resolve(execPath.getFileName() + ext.toLowerCase()); without using toRealPath.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think Windows is mapping the case of the name... I think it's because the command was launched just as podman rather than as podman.exe or podman.EXE or anything else. The file name does not get passed to the command AFAIK, just the command name which was used to execute the program.
I'm not sure it's possible to do this from Java though. I recall we had some problems when trying to execute a program without its extension.
Edited to add: Perhaps this is one reason why many launchers try to launch via cmd.exe.
|
Also @Eng-Fouad, will it actually cause issues, except for this version detection? What exactly happens in this case, we run podman successfully but the output of the version contains To be honest, I think we should be more permissive in the
|
db3392f to
7a6b8a0
Compare
Sure. I will try to add some tests later in a separate PR. |
Usually Windows FS is case-insensitive (i.e. you cannot have
While this PR should resolve the issue in Quarkus, I am ok with modifying the pattern to be more permissive. Do you want me to open PR in Quarkus repo? |
This is specifically a bug in podman, IMO (albeit an arguably minor one), so regardless of what we do here, we should report the bug upstream as well. |
I think this should be fixed specifically for this bit of code: I.e. make the regex be case-insensitive for the part which detects the file extension. Whether or not we fix |
|
@gsmet I did not add |
7a6b8a0 to
960a39f
Compare
Currently,
ProcessUtil.pathOfCommand(Path.of("docker"))will returnC:\Program Files\Docker\Docker\resources\bin\docker.EXEinstead ofC:\Program Files\Docker\Docker\resources\bin\docker.exe.This PR will fix a recent bug in latest Quarkus with podman detection on Windows:
Notice that the podman version output pattern expects that the
.exemust be in lower case if exist.I thought about fixing this bug in Quarkus repo, but I noticed that
ProcessUtil.pathOfCommandis used in many places in Quarkus codebase, so fixing it here could potentially fix other bugs.