Skip to content

Commit cdc3305

Browse files
committed
Better tests for non unicode strings
1 parent f2a02c1 commit cdc3305

File tree

3 files changed

+96
-32
lines changed

3 files changed

+96
-32
lines changed

src/cli/self_update/test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub fn get_path() -> Option<RegValue> {
1919
Ok(val) => Some(val),
2020
Err(ref e) if e.kind() == std::io::ErrorKind::NotFound => None,
2121
Err(e) => panic!(
22-
"Error getting PATH: {}\nBetter abort to avoid trahsing it.",
22+
"Error getting PATH: {}\nBetter abort to avoid trashing it.",
2323
e
2424
),
2525
}

src/cli/self_update/windows.rs

Lines changed: 50 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -437,37 +437,22 @@ mod tests {
437437
}
438438

439439
#[test]
440-
fn windows_doesnt_mess_with_a_non_string_path() {
441-
// This writes an error, so we want a sink for it.
442-
let tp = Box::new(currentprocess::TestProcess {
443-
vars: [("HOME".to_string(), "/unused".to_string())]
444-
.iter()
445-
.cloned()
446-
.collect(),
447-
..Default::default()
448-
});
449-
with_saved_path(&|| {
450-
currentprocess::with(tp.clone(), || {
451-
let root = RegKey::predef(HKEY_CURRENT_USER);
452-
let environment = root
453-
.open_subkey_with_flags("Environment", KEY_READ | KEY_WRITE)
454-
.unwrap();
455-
let reg_value = RegValue {
456-
bytes: vec![0x00, 0xD8, 0x01, 0x01, 0x00, 0x00],
457-
vtype: RegType::REG_BINARY,
458-
};
459-
environment.set_raw_value("PATH", &reg_value).unwrap();
460-
// Ok(None) signals no change to the PATH setting layer
461-
assert_eq!(
462-
None,
463-
super::_with_path_cargo_home_bin(|_, _| panic!("called")).unwrap()
464-
);
465-
})
466-
});
440+
fn windows_handle_non_unicode_path() {
441+
let initial_path = vec![
442+
0xD800, // leading surrogate
443+
0x0101, // bogus trailing surrogate
444+
0x0000, // null
445+
];
446+
let cargo_home = wide(r"c:\users\example\.cargo\bin");
447+
let final_path = [&cargo_home, &[b';' as u16][..], &initial_path].join(&[][..]);
448+
467449
assert_eq!(
468-
r"warning: the registry key HKEY_CURRENT_USER\Environment\PATH is not a string. Not modifying the PATH variable
469-
",
470-
String::from_utf8(tp.get_stderr()).unwrap()
450+
&final_path,
451+
&super::_add_to_path(initial_path.clone(), cargo_home.clone(),).unwrap()
452+
);
453+
assert_eq!(
454+
&initial_path,
455+
&super::_remove_from_path(final_path, cargo_home,).unwrap()
471456
);
472457
}
473458

@@ -536,6 +521,41 @@ mod tests {
536521
});
537522
}
538523

524+
#[test]
525+
fn windows_doesnt_mess_with_a_non_string_path() {
526+
// This writes an error, so we want a sink for it.
527+
let tp = Box::new(currentprocess::TestProcess {
528+
vars: [("HOME".to_string(), "/unused".to_string())]
529+
.iter()
530+
.cloned()
531+
.collect(),
532+
..Default::default()
533+
});
534+
with_saved_path(&|| {
535+
currentprocess::with(tp.clone(), || {
536+
let root = RegKey::predef(HKEY_CURRENT_USER);
537+
let environment = root
538+
.open_subkey_with_flags("Environment", KEY_READ | KEY_WRITE)
539+
.unwrap();
540+
let reg_value = RegValue {
541+
bytes: vec![0x12, 0x34],
542+
vtype: RegType::REG_BINARY,
543+
};
544+
environment.set_raw_value("PATH", &reg_value).unwrap();
545+
// Ok(None) signals no change to the PATH setting layer
546+
assert_eq!(
547+
None,
548+
super::_with_path_cargo_home_bin(|_, _| panic!("called")).unwrap()
549+
);
550+
})
551+
});
552+
assert_eq!(
553+
r"warning: the registry key HKEY_CURRENT_USER\Environment\PATH is not a string. Not modifying the PATH variable
554+
",
555+
String::from_utf8(tp.get_stderr()).unwrap()
556+
);
557+
}
558+
539559
#[test]
540560
fn windows_treat_missing_path_as_empty() {
541561
// during install the PATH key may be missing; treat it as empty

tests/cli-paths.rs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,6 @@ mod windows {
309309
use crate::mock::clitools::{self, expect_ok, Scenario};
310310

311311
#[test]
312-
#[cfg(windows)]
313312
/// Smoke test for end-to-end code connectivity of the installer path mgmt on windows.
314313
fn install_uninstall_affect_path() {
315314
clitools::setup(Scenario::Empty, &|config| {
@@ -330,4 +329,49 @@ mod windows {
330329
})
331330
});
332331
}
332+
333+
#[test]
334+
/// Smoke test for end-to-end code connectivity of the installer path mgmt on windows.
335+
fn install_uninstall_affect_path_with_non_unicode() {
336+
use std::ffi::OsString;
337+
use std::os::windows::ffi::OsStrExt;
338+
use winreg::enums::{RegType, HKEY_CURRENT_USER, KEY_READ, KEY_WRITE};
339+
use winreg::{RegKey, RegValue};
340+
341+
clitools::setup(Scenario::Empty, &|config| {
342+
with_saved_path(&|| {
343+
// Set up a non unicode PATH
344+
let reg_value = RegValue {
345+
bytes: vec![
346+
0x00, 0xD8, // leading surrogate
347+
0x01, 0x01, // bogus trailing surrogate
348+
0x00, 0x00, // null
349+
],
350+
vtype: RegType::REG_EXPAND_SZ,
351+
};
352+
RegKey::predef(HKEY_CURRENT_USER)
353+
.open_subkey_with_flags("Environment", KEY_READ | KEY_WRITE)
354+
.unwrap()
355+
.set_raw_value("PATH", &reg_value)
356+
.unwrap();
357+
358+
// compute expected path after installation
359+
let expected = RegValue {
360+
bytes: OsString::from(config.cargodir.join("bin"))
361+
.encode_wide()
362+
.flat_map(|v| vec![v as u8, (v >> 8) as u8])
363+
.chain(vec![b';', 0])
364+
.chain(reg_value.bytes.iter().copied())
365+
.collect(),
366+
vtype: RegType::REG_EXPAND_SZ,
367+
};
368+
369+
expect_ok(config, &INIT_NONE);
370+
assert_eq!(get_path().unwrap(), expected);
371+
372+
expect_ok(config, &["rustup", "self", "uninstall", "-y"]);
373+
assert_eq!(get_path().unwrap(), reg_value);
374+
})
375+
});
376+
}
333377
}

0 commit comments

Comments
 (0)