mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 02:57:44 +00:00
ls: fix the GNU test tests/ls/selinux.sh (#8281)
* ls: fix the GNU test tests/ls/selinux.sh * Remove old comment Co-authored-by: Daniel Hofstetter <daniel.hofstetter@42dh.com> * simpli Co-authored-by: Daniel Hofstetter <daniel.hofstetter@42dh.com> --------- Co-authored-by: Daniel Hofstetter <daniel.hofstetter@42dh.com>
This commit is contained in:
parent
0923b92921
commit
d04d0cd987
3 changed files with 114 additions and 9 deletions
|
@ -52,4 +52,4 @@ name = "ls"
|
|||
path = "src/main.rs"
|
||||
|
||||
[features]
|
||||
feat_selinux = ["selinux"]
|
||||
feat_selinux = ["selinux", "uucore/selinux"]
|
||||
|
|
|
@ -1900,11 +1900,7 @@ impl PathData {
|
|||
None => OnceCell::new(),
|
||||
};
|
||||
|
||||
let security_context = if config.context {
|
||||
get_security_context(config, &p_buf, must_dereference)
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
let security_context = get_security_context(config, &p_buf, must_dereference);
|
||||
|
||||
Self {
|
||||
md: OnceCell::new(),
|
||||
|
@ -3339,7 +3335,10 @@ fn get_security_context(config: &Config, p_buf: &Path, must_dereference: bool) -
|
|||
Err(err) => {
|
||||
// The Path couldn't be dereferenced, so return early and set exit code 1
|
||||
// to indicate a minor error
|
||||
show!(LsError::IOErrorContext(p_buf.to_path_buf(), err, false));
|
||||
// Only show error when context display is requested to avoid duplicate messages
|
||||
if config.context {
|
||||
show!(LsError::IOErrorContext(p_buf.to_path_buf(), err, false));
|
||||
}
|
||||
return substitute_string;
|
||||
}
|
||||
Ok(_md) => (),
|
||||
|
|
|
@ -4263,8 +4263,7 @@ fn test_ls_context_long() {
|
|||
let line: Vec<_> = result.stdout_str().split(' ').collect();
|
||||
assert!(line[0].ends_with('.'));
|
||||
assert!(line[4].starts_with("unconfined_u"));
|
||||
let s: Vec<_> = line[4].split(':').collect();
|
||||
assert!(s.len() == 4);
|
||||
validate_selinux_context(line[4]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4298,6 +4297,113 @@ fn test_ls_context_format() {
|
|||
}
|
||||
}
|
||||
|
||||
/// Helper function to validate `SELinux` context format
|
||||
#[cfg(feature = "feat_selinux")]
|
||||
fn validate_selinux_context(context: &str) {
|
||||
assert!(
|
||||
context.contains(':'),
|
||||
"Expected SELinux context format (user:role:type:level), got: {}",
|
||||
context
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
context.split(':').count(),
|
||||
4,
|
||||
"SELinux context should have 4 components separated by colons, got: {}",
|
||||
context
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "feat_selinux")]
|
||||
fn test_ls_selinux_context_format() {
|
||||
if !uucore::selinux::is_selinux_enabled() {
|
||||
println!("test skipped: Kernel has no support for SElinux context");
|
||||
return;
|
||||
}
|
||||
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
|
||||
at.touch("file");
|
||||
at.symlink_file("file", "link");
|
||||
|
||||
// Test that ls -lnZ properly shows the context
|
||||
for file in ["file", "link"] {
|
||||
let result = scene.ucmd().args(&["-lnZ", file]).succeeds();
|
||||
let output = result.stdout_str();
|
||||
|
||||
let lines: Vec<&str> = output.lines().collect();
|
||||
assert!(!lines.is_empty(), "Output should contain at least one line");
|
||||
|
||||
let first_line = lines[0];
|
||||
let parts: Vec<&str> = first_line.split_whitespace().collect();
|
||||
assert!(parts.len() >= 6, "Line should have at least 6 fields");
|
||||
|
||||
// The 5th field (0-indexed position 4) should contain the SELinux context
|
||||
// Format: permissions links owner group context size date time name
|
||||
let context = parts[4];
|
||||
validate_selinux_context(context);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "feat_selinux")]
|
||||
fn test_ls_selinux_context_indicator() {
|
||||
if !uucore::selinux::is_selinux_enabled() {
|
||||
println!("test skipped: Kernel has no support for SElinux context");
|
||||
return;
|
||||
}
|
||||
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
|
||||
at.touch("file");
|
||||
at.symlink_file("file", "link");
|
||||
|
||||
// Test that ls -l shows "." indicator for files with SELinux contexts
|
||||
for file in ["file", "link"] {
|
||||
let result = scene.ucmd().args(&["-l", file]).succeeds();
|
||||
let output = result.stdout_str();
|
||||
|
||||
// The 11th character should be "." indicating SELinux context
|
||||
// -rw-rw-r--. (permissions + context indicator)
|
||||
let lines: Vec<&str> = output.lines().collect();
|
||||
assert!(!lines.is_empty(), "Output should contain at least one line");
|
||||
|
||||
let first_line = lines[0];
|
||||
let chars: Vec<char> = first_line.chars().collect();
|
||||
assert!(
|
||||
chars.len() >= 11,
|
||||
"Line should be at least 11 characters long"
|
||||
);
|
||||
|
||||
// The 11th character (0-indexed position 10) should be "." for SELinux context
|
||||
assert_eq!(
|
||||
chars[10], '.',
|
||||
"Expected '.' indicator for SELinux context in position 11, got '{}' in line: {}",
|
||||
chars[10], first_line
|
||||
);
|
||||
}
|
||||
|
||||
// Test that ls -lnZ properly shows the context
|
||||
for file in ["file", "link"] {
|
||||
let result = scene.ucmd().args(&["-lnZ", file]).succeeds();
|
||||
let output = result.stdout_str();
|
||||
|
||||
let lines: Vec<&str> = output.lines().collect();
|
||||
assert!(!lines.is_empty(), "Output should contain at least one line");
|
||||
|
||||
let first_line = lines[0];
|
||||
let parts: Vec<&str> = first_line.split_whitespace().collect();
|
||||
assert!(parts.len() >= 6, "Line should have at least 6 fields");
|
||||
|
||||
// The 5th field (0-indexed position 4) should contain the SELinux context
|
||||
// Format: permissions links owner group context size date time name
|
||||
validate_selinux_context(parts[4]);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(non_snake_case)]
|
||||
fn test_ls_a_A() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue