Skip to content

Commit f71d596

Browse files
committed
Test on Windows with an actual file called NUL
This covers a possible concern pertaining to a forthcoming minor gix-testtools bugfix. The null device, accessible as `/dev/null` on a Unix-like system, or as `NUL` (and in some other ways) on Windows, is the best candidate to replace the current value of `:` (on Unix) or `-` (on Windows) for `GIT_CONFIG_SYSTEM` and `GIT_CONFIG_GLOBAL` when test fixture scripts are running. This is because the filenames `:` (on Unix) and `-` (on Windows) do not have any special meaning. They are valid but unusual filenames; files of these names most often do not exist, but can, and when they do, their contents are used the populate the system or global scope for test fixtures, which is not the intended behavior. `git` does not treat them as anything but filenames: a `:` is not treated as a separator because those variables are interpreted as single paths rather than lists of paths, and a `-` is not treated to mean standard input (or any other special data source) because it appears in an environment variable rather than as a command-line argument. But `/dev/null` and `NUL` can exist, too. On Unix, where `/dev/null` should be used, the whole point is that `/dev/null` exists. That absolute path is not treated specially. Instead, the device node for the null device is linked there. On Windows, where the null device is named `NUL`, an entry for it with that name does also sort of exist in the filesystem, accessible via the fully qualified device path `\\.\NUL` as well as by some other fully qualified forms such as `\??\NUL`. However, not all interfaces support all path forms, so accessing it in those ways is not necessarily more robust than accessing it with the relative path `NUL`. Yet it is possible for an actual file, not the null device, to exist with the name `NUL` in an arbitrary directory. Such a file can only be referred to using the UNC syntax with a `\\?\` prefixed path (not to be confused with the `\\.\` device namespace prefix, nor the NT `\??\` prefix). When such a file exists, `NUL` itself still does not refer to it; `NUL` still refers to the null device. The additon to the test here (and refactorings to support it) create an acutal file called `NUL` to demonstrate that changing `-` to `NUL` really does avoid getting a configuration file, regardless of what files exist.
1 parent 7186eed commit f71d596

File tree

1 file changed

+11
-9
lines changed

1 file changed

+11
-9
lines changed

tests/tools/src/lib.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -887,16 +887,18 @@ mod tests {
887887

888888
fn check_configure_clears_scope(scope_env_key: &str, scope_option: &str) {
889889
let scope_env_value = "gitconfig";
890-
891-
#[cfg(windows)]
892-
let names = [scope_env_value, "-"];
893-
#[cfg(not(windows))]
894-
let names = [scope_env_value, "-", ":"];
895-
896890
let temp = tempfile::TempDir::new().expect("can create temp dir");
891+
let dir = temp.path();
892+
893+
let paths: &[PathBuf] = if cfg!(windows) {
894+
let unc_literal_nul = dir.canonicalize().expect("directory exists").join("NUL");
895+
&[dir.join(scope_env_value), dir.join("-"), unc_literal_nul]
896+
} else {
897+
&[dir.join(scope_env_value), dir.join("-"), dir.join(":")]
898+
};
897899

898-
for name in names {
899-
File::create_new(temp.path().join(name))
900+
for path in paths {
901+
File::create_new(path)
900902
.expect("can create file")
901903
.write_all(b"[foo]\n\tbar = baz\n")
902904
.expect("can write contents");
@@ -905,7 +907,7 @@ mod tests {
905907
let mut cmd = std::process::Command::new("git");
906908
cmd.env(scope_env_key, scope_env_value); // configure_command() should override it.
907909
let args = ["config", "-l", "--show-origin", scope_option].map(String::from);
908-
configure_command(&mut cmd, &args, temp.path());
910+
configure_command(&mut cmd, &args, dir);
909911

910912
let output = cmd.output().expect("can run git");
911913
let stdout = output.stdout.to_str().expect("valid UTF-8");

0 commit comments

Comments
 (0)