Skip to content

Use verbatim paths for process::Command if necessary#92519

Merged
bors merged 2 commits into
rust-lang:masterfrom
ChrisDenton:command-maybe-verbatim
Mar 19, 2022
Merged

Use verbatim paths for process::Command if necessary#92519
bors merged 2 commits into
rust-lang:masterfrom
ChrisDenton:command-maybe-verbatim

Conversation

@ChrisDenton

Copy link
Copy Markdown
Member

In #89174, the standard library started using verbatim paths so longer paths are usable by default. However, Command was originally left out because of the way CreateProcessW was being called. This was changed as a side effect of #87704 so now Command paths can be converted to verbatim too (if necessary).

@rust-highfive

Copy link
Copy Markdown
Contributor

r? @joshtriplett

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jan 3, 2022
@bors

bors commented Jan 5, 2022

Copy link
Copy Markdown
Collaborator

☔ The latest upstream changes (presumably #92580) made this pull request unmergeable. Please resolve the merge conflicts.

@ChrisDenton ChrisDenton force-pushed the command-maybe-verbatim branch from c95249c to 2bfd6f8 Compare January 5, 2022 17:08
@joshtriplett joshtriplett added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label Jan 9, 2022
@joshtriplett

Copy link
Copy Markdown
Member

Seems reasonable to me.

@rfcbot merge

@rfcbot

rfcbot commented Jan 9, 2022

Copy link
Copy Markdown

Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@rfcbot rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. labels Jan 9, 2022
@rfcbot

rfcbot commented Jan 12, 2022

Copy link
Copy Markdown

🔔 This is now entering its final comment period, as per the review above. 🔔

@rfcbot rfcbot removed the proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. label Jan 12, 2022
@rfcbot rfcbot added the finished-final-comment-period The final comment period is finished for this PR / Issue. label Jan 22, 2022
@rfcbot

rfcbot commented Jan 22, 2022

Copy link
Copy Markdown

The final comment period, with a disposition to merge, as per the review above, is now complete.

As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

This will be merged soon.

@rfcbot rfcbot added to-announce Announce this issue on triage meeting and removed final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. labels Jan 22, 2022
@apiraino apiraino removed the to-announce Announce this issue on triage meeting label Feb 1, 2022
@ChrisDenton

Copy link
Copy Markdown
Member Author

@joshtriplett this can be merged now?

@ChrisDenton ChrisDenton force-pushed the command-maybe-verbatim branch from 2bfd6f8 to 93f627d Compare February 17, 2022 13:21
@ChrisDenton

ChrisDenton commented Feb 17, 2022

Copy link
Copy Markdown
Member Author

Rebased after #91182 was merged (which didn't cause a merge conflict but does break this PR). The first commit is the same as before. The second fixes program_exists to use maybe_verbatim and the resolver to reuse the UTF-16 encoded path rather than having to re-encode it again. That last bit isn't strictly necessary here and could be a separate PR if it would be easier.

@dtolnay dtolnay assigned dtolnay and unassigned joshtriplett Mar 18, 2022

@dtolnay dtolnay left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@dtolnay

dtolnay commented Mar 18, 2022

Copy link
Copy Markdown
Member

@bors r+

@bors

bors commented Mar 18, 2022

Copy link
Copy Markdown
Collaborator

📌 Commit 93f627d has been approved by dtolnay

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 18, 2022
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this pull request Mar 19, 2022
… r=dtolnay

Use verbatim paths for `process::Command` if necessary

In rust-lang#89174, the standard library started using verbatim paths so longer paths are usable by default. However, `Command` was originally left out because of the way `CreateProcessW` was being called. This was changed as a side effect of rust-lang#87704 so now `Command` paths can be converted to verbatim too (if necessary).
This was referenced Mar 19, 2022
bors added a commit to rust-lang-ci/rust that referenced this pull request Mar 19, 2022
Rollup of 6 pull requests

Successful merges:

 - rust-lang#92519 (Use verbatim paths for `process::Command` if necessary)
 - rust-lang#92612 (Update stdlib for the l4re target)
 - rust-lang#92663 (Implement `Write for Cursor<[u8; N]>`, plus `A: Allocator` cursor support)
 - rust-lang#93263 (Consistently present absent stdio handles on Windows as NULL handles.)
 - rust-lang#93692 (keyword_docs: document use of `in` with `pub` keyword)
 - rust-lang#94984 (add `CStr` method that accepts any slice containing a nul-terminated string)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit ba2d5ed into rust-lang:master Mar 19, 2022
@rustbot rustbot added this to the 1.61.0 milestone Mar 19, 2022
@dtolnay dtolnay added the O-windows Operating system: Windows label Mar 20, 2022
messense added a commit to rust-cross/cargo-zigbuild that referenced this pull request Mar 20, 2022
messense added a commit to rust-cross/cargo-zigbuild that referenced this pull request Mar 20, 2022
@ChrisDenton ChrisDenton deleted the command-maybe-verbatim branch April 28, 2022 20:25
ChrisDenton added a commit to ChrisDenton/rust that referenced this pull request Apr 29, 2022
…erbatim, r=dtolnay"

This reverts commit ba2d5ed, reversing
changes made to 9b701e7.
Mark-Simulacrum pushed a commit to Mark-Simulacrum/rust that referenced this pull request May 13, 2022
…erbatim, r=dtolnay"

This reverts commit ba2d5ed, reversing
changes made to 9b701e7.
bors added a commit to rust-lang-ci/rust that referenced this pull request May 14, 2022
…ulacrum

[beta] backports

This backports/rolls up:

*  Quick fix for rust-lang#96223. rust-lang#96679
*  [beta] Revert rust-lang#92519 on beta rust-lang#96556
*  [beta] Clippy backport ICE/infinite loop fix rust-lang#96740
*  Revert "Prefer projection candidates instead of param_env candidates for Sized predicates" rust-lang#96593
MabezDev pushed a commit to esp-rs/rust that referenced this pull request May 17, 2022
…erbatim, r=dtolnay"

This reverts commit ba2d5ed, reversing
changes made to 9b701e7.
rdesgroppes added a commit to rdesgroppes/bazel that referenced this pull request Jun 21, 2026
### Description

AsExecutablePathForCreateProcess shortens an executable's path with
GetShortPathNameW so it fits CreateProcessW's MAX_PATH-bound command
line, and currently fails outright when shortening can't bring it
under MAX_PATH.
This change adds a fallback: it launches the executable through
CreateProcessW's lpApplicationName, which is not subject to MAX_PATH,
in extended-length ("\\?\") form, keeping the original long path as
argv[0] in the command line.

Shortening is still attempted first, so the change is a pure superset
of the current behavior: paths that shorten today are launched
unchanged, and only the currently-failing ones take the fallback.
The fallback is limited to absolute, normalized paths to plain
executables; a batch file is not a valid lpApplicationName, as it
must be run through a command interpreter.

Verified at two levels: a util_test case that synthesizes an
unshortenable path, and a WindowsProcessesTest case that launches
cmd.exe from a >MAX_PATH directory of already-8dot3 components.

### Motivation

Fixes bazelbuild#19710.
Shortening fails in two situations, both handled here:

- 8dot3 short-name creation is disabled on the volume (common in
  containers), so GetShortPathNameW is a no-op and a long runfiles
  executable path stays over MAX_PATH;
- the path is nested so deeply that even fully 8dot3-shortened it
  still overflows MAX_PATH.

The fix relies on "\\?\" bypassing MAX_PATH at the path-parsing
layer, independently of the LongPathsEnabled registry value and the
longPathAware manifest.

Prior art: Rust's std::process::Command passes a verbatim "\\?\" path
as lpApplicationName for a >MAX_PATH executable and special-cases
batch files the same way (rust-lang/rust#92519, rust-lang/rust#87704).

### Build API Changes

No

### Checklist

- [x] I have added tests for the new use cases (if any).
- [ ] I have updated the documentation (if applicable).

### Release Notes

RELNOTES: Fixed Bazel being unable to run a Windows executable whose
path is too long to shorten under MAX_PATH, e.g. when 8dot3 short
names are disabled (microsoft/Windows-Containers#507).
rdesgroppes added a commit to rdesgroppes/bazel that referenced this pull request Jun 21, 2026
### Description

`AsExecutablePathForCreateProcess` shortens an executable's path with
`GetShortPathNameW` so it fits `CreateProcessW`'s `MAX_PATH`-bound
command line, and currently fails outright when shortening can't bring
it under `MAX_PATH`.
This change adds a fallback: it launches the executable through
`CreateProcessW`'s _lpApplicationName_, which is not subject to the
`MAX_PATH` limit, in extended-length (`\\?\`) form.
Supplying _lpApplicationName_ also lifts the `MAX_PATH` limit from the
executable part of _lpCommandLine_, so the original path is kept there
as `argv[0]`.

Shortening is still attempted first, so the change is a pure superset of
the current behavior: paths that shorten today are launched unchanged,
and only the currently-failing ones take the fallback.
The fallback is limited to absolute, normalized paths to plain
executables:
- a batch file is not a valid _lpApplicationName_ as it must be run
  through a command interpreter,
- neither is a non-normalized path because its `.`/`..` components would
  survive unresolved in the extended-length path.

The fix relies on `\\?\` bypassing `MAX_PATH` at the path-parsing layer,
independently of the _LongPathsEnabled_ registry value and the
_longPathAware_ manifest.

### Motivation
Fixes bazelbuild#19710.

Shortening fails in two situations, both handled here:
- 8dot3 short-name creation is disabled on the volume (common in
  containers, microsoft/Windows-Containers#507), so `GetShortPathNameW`
  is a no-op and a long runfiles executable path stays over `MAX_PATH`,
- the path is nested so deeply that even fully 8dot3-shortened it still
  overflows `MAX_PATH`.

Prior art: Rust's `std::process::Command` passes a verbatim `\\?\` path
as _lpApplicationName_ for a >`MAX_PATH` executable and special-cases
batch files the same way (rust-lang/rust#87704, rust-lang/rust#92519).

### Build API Changes

No

### Checklist

- [x] I have added tests for the new use cases (if any).
- [ ] I have updated the documentation (if applicable).

### Release Notes

RELNOTES: Fixed Bazel being unable to run a Windows executable whose
path is too long to shorten under `MAX_PATH`, e.g. when 8dot3 short
names are disabled (microsoft/Windows-Containers#507).
rdesgroppes added a commit to rdesgroppes/bazel that referenced this pull request Jun 22, 2026
### Description

`AsExecutablePathForCreateProcess` shortens an executable's path with
`GetShortPathNameW` so it fits `CreateProcessW`'s `MAX_PATH`-bound
command line, and currently fails outright when shortening can't bring
it under `MAX_PATH`.
This change adds a fallback: it launches the executable through
`CreateProcessW`'s _lpApplicationName_, which is not subject to the
`MAX_PATH` limit, in extended-length (`\\?\`) form.
Supplying _lpApplicationName_ also lifts the `MAX_PATH` limit from the
executable part of _lpCommandLine_, so the original path is kept there
as `argv[0]`.

Shortening is still attempted first, so the change is a pure superset of
the current behavior: paths that shorten today are launched unchanged,
and only the currently-failing ones take the fallback.
The fallback is limited to absolute, normalized paths to plain
executables:
- a batch file is not a valid _lpApplicationName_ as it must be run
  through a command interpreter,
- neither is a non-normalized path because its `.`/`..` components would
  survive unresolved in the extended-length path.

The fix relies on `\\?\` bypassing `MAX_PATH` at the path-parsing layer,
independently of the _LongPathsEnabled_ registry value and the
_longPathAware_ manifest.

### Motivation
Fixes bazelbuild#19710.

Shortening fails in two situations, both handled here:
- 8dot3 short-name creation is disabled on the volume (common in
  containers, microsoft/Windows-Containers#507), so `GetShortPathNameW`
  is a no-op and a long runfiles executable path stays over `MAX_PATH`,
- the path is nested so deeply that even fully 8dot3-shortened it still
  overflows `MAX_PATH`.

Prior art: Rust's `std::process::Command` passes a verbatim `\\?\` path
as _lpApplicationName_ for a >`MAX_PATH` executable and special-cases
batch files the same way (rust-lang/rust#87704, rust-lang/rust#92519).

### Build API Changes

No

### Checklist

- [x] I have added tests for the new use cases (if any).
- [ ] I have updated the documentation (if applicable).

### Release Notes

RELNOTES: Fixed Bazel being unable to run a Windows executable whose
path is too long to shorten under `MAX_PATH`, e.g. when 8dot3 short
names are disabled (microsoft/Windows-Containers#507).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. O-windows Operating system: Windows S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants