Skip to content

Commit df175bc

Browse files
committed
Rename helper; condense huge comment and move into position
1 parent c486a7d commit df175bc

File tree

1 file changed

+11
-61
lines changed

1 file changed

+11
-61
lines changed

gix-path/src/env/git.rs

Lines changed: 11 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -15,82 +15,32 @@ pub(super) static ALTERNATIVE_LOCATIONS: Lazy<Vec<PathBuf>> = Lazy::new(|| {
1515
#[cfg(not(windows))]
1616
pub(super) static ALTERNATIVE_LOCATIONS: Lazy<Vec<PathBuf>> = Lazy::new(|| vec![]);
1717

18-
#[cfg(any(windows, test))] // So this can always be tested.
19-
fn alternative_locations_from_env<F>(var_os_func: F) -> Vec<PathBuf>
18+
#[cfg(any(windows, test))]
19+
fn alternative_windows_locations_from_environment<F>(var_os_func: F) -> Vec<PathBuf>
2020
where
2121
F: Fn(&str) -> Option<std::ffi::OsString>,
2222
{
23-
// I am not really sure what this should do to handle the ProgramFiles environment variable and
24-
// figure out if it is 64-bit or 32-bit -- which we need in order to know whether to append
25-
// `Git/mingw64/bin` or `Git/mingw32/bin`. We do need to look at the ProgramFiles environment
26-
// variable in addition to the other two preferable architecture-specific ones (for which the
27-
// mingw64 vs. mingw32 decision is easy), at least some of the time, for two reasons.
28-
//
29-
// First, we may be on a 32-bit system. Then we do not have either of the other two variables.
30-
//
31-
// Second, the others may also absent on a 64-bit system, if a parent process whittles down the
32-
// variables to pass to this child process, out of an erroneous belief about which ones are
33-
// needed to provide access to the program files directory.
34-
//
35-
// On a 64-bit system, the way a child process inherits its ProgramFiles variable to be for its
36-
// own architecture -- since after all its parent's architecture could be different -- is:
37-
//
38-
// - The value of a 64-bit child's ProgramFiles variable comes from whatever the parent passed
39-
// down as ProgramW6432, if that variable was passed down.
40-
//
41-
// - The value of a 32-bit child's ProgramFiles variable comes from whatever the parent passed
42-
// down as ProgramFiles(x86), if that variable was passed down.
43-
//
44-
// - If the variable corresponding to the child's architecture was not passed down by the
45-
// parent, but ProgramFiles was passed down, then the child receives that as the value of
46-
// its ProgramFiles variable. Only in this case does ProgramFiles come from ProgramFiles.
47-
//
48-
// The problem -- besides that those rules are not well known, and parent processes that seek
49-
// to pass down minimal environments often do not take heed of them, such that a child process
50-
// will get the wrong architecture's value for its ProgramFiles environment variable -- is that
51-
// the point of this function is to make use of environment variables in order to avoid:
52-
//
53-
// - Calling Windows API functions explicitly, even via the higher level `windows` crate.
54-
// - Accessing the Windows registry, even through the very widely used `winreg` crate.
55-
// - Adding any significant new production dependencies, such as the `known-folders` crate.
56-
//
57-
// Possible solutions:
58-
//
59-
// 1. Abandon at least one of those goals.
60-
// 2. Check both `mingw*` subdirectories regardless of which program files Git is in.
61-
// 3. Inspect the names for substrings like ` (x86)` in an expected position.
62-
// 4. Assume the value of `ProgramFiles` is correct, i.e., is for the process's architecture.
63-
//
64-
// I think (4) is the way to go, at least until (1) is assessed. With (2), we would be checking
65-
// paths that there is no specific reason to think have *working* Git executables...though this
66-
// does have the advantage that its logic would be the same as would be needed in the local
67-
// program files directory (usually `%LocalAppData$/Programs`) if we ever add that. With (3),
68-
// the risk of getting it wrong is low, but the logic is more complex, and we lose the
69-
// simplicity of getting the paths from outside rather than applying assumptions about them.
70-
//
71-
// With (4), we take the ProgramFiles environment variable at its word. This is good not just
72-
// for abstract correctness, but also if the parent modifies these variables intentionally on a
73-
// 64-bit system. A parent process can't reasonably expect this to be followed, because a child
74-
// process may use another mechanism such as known folders. However, following it, when we are
75-
// using environment variables already, satisfies a weaker expectation that the environment
76-
// value *or* actual value (obtainable via known folders or the registry), rather than some
77-
// third value, is used. (4) is also a simple way to do the right thing on a 32-bit system.
78-
7923
// Should give a 64-bit program files path from a 32-bit or 64-bit process on a 64-bit system.
8024
let varname_64bit = "ProgramW6432";
8125

8226
// Should give a 32-bit program files path from a 32-bit or 64-bit process on a 64-bit system.
8327
// This variable is x86-specific, but neither Git nor Rust target 32-bit ARM on Windows.
8428
let varname_x86 = "ProgramFiles(x86)";
8529

86-
// Should give a 32-bit program files path on a 32-bit system. We also need to check it on a
87-
// 64-bit system. [FIXME: Somehow briefly explain why we still need to do that.]
30+
// Should give a 32-bit program files path on a 32-bit system. We also check this on a 64-bit
31+
// system, even though it *should* equal the process architecture specific variable, so that we
32+
// cover the case of a parent process that passes down an overly sanitized environment that
33+
// lacks the architecture-specific variable. On a 64-bit system, because parent and child
34+
// processes' architectures can be different, Windows sets the child's ProgramFiles variable
35+
// from the ProgramW6432 or ProgramFiles(x86) variable applicable to the child's architecture.
36+
// Only if the parent does not pass that down is the passed-down ProgramFiles variable even
37+
// used. But this behavior is not well known, so that situation does sometimes happen.
8838
let varname_current = "ProgramFiles";
8939

9040
// 64-bit relative bin dir. So far, this is always mingw64, not ucrt64, clang64, or clangarm64.
9141
let suffix_64 = Path::new("bin/mingw64");
9242

93-
// 32-bit relative bin dir. This is always mingw32, not clang32.
43+
// 32-bit relative bin dir. So far, this is always mingw32, not clang32.
9444
let suffix_32 = Path::new("bin/mingw32");
9545

9646
// Whichever of the 64-bit or 32-bit relative bin better matches this process's architecture.

0 commit comments

Comments
 (0)