mirror of
https://github.com/uutils/coreutils
synced 2024-11-16 09:48:03 +00:00
ls: (--context/-Z) add support for invalid utf8
If security context byte slice contains invalid utf8: * issue warning * show replacement characters for invalid utf8 sequences
This commit is contained in:
parent
e018a45b54
commit
cd2153eac6
2 changed files with 43 additions and 12 deletions
|
@ -40,6 +40,7 @@ use std::{
|
|||
time::Duration,
|
||||
};
|
||||
use term_grid::{Cell, Direction, Filling, Grid, GridOptions};
|
||||
use uucore::display::Quotable;
|
||||
use uucore::error::{set_exit_code, FromIo, UError, UResult};
|
||||
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
|
@ -1256,27 +1257,41 @@ impl PathData {
|
|||
None => OnceCell::new(),
|
||||
};
|
||||
|
||||
let substitute_string = "?".to_string();
|
||||
let security_context = if config.context {
|
||||
if config.selinux_supported {
|
||||
#[cfg(feature = "selinux")]
|
||||
{
|
||||
if let Ok(Some(context)) =
|
||||
selinux::SecurityContext::of_path(&p_buf, must_dereference, false)
|
||||
{
|
||||
String::from_utf8_lossy(context.as_bytes())
|
||||
.trim_end_matches(char::from(0))
|
||||
.to_string()
|
||||
} else {
|
||||
// TODO: print warning with error to stderr
|
||||
"?".to_string()
|
||||
match selinux::SecurityContext::of_path(&p_buf, must_dereference, false) {
|
||||
Err(_r) => {
|
||||
// TODO: show the actual reason why it failed
|
||||
show_warning!("failed to get security context of: {}", p_buf.quote());
|
||||
substitute_string
|
||||
}
|
||||
Ok(None) => substitute_string,
|
||||
Ok(Some(context)) => {
|
||||
let mut context = context.as_bytes();
|
||||
if context.ends_with(&[0]) {
|
||||
// TODO: replace with `strip_prefix()` when MSRV >= 1.51
|
||||
context = &context[..context.len() - 1]
|
||||
};
|
||||
String::from_utf8(context.to_vec()).unwrap_or_else(|e| {
|
||||
show_warning!(
|
||||
"getting security context of: {}: {}",
|
||||
p_buf.quote(),
|
||||
e.to_string()
|
||||
);
|
||||
String::from_utf8_lossy(context).into_owned()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "selinux"))]
|
||||
{
|
||||
"?".to_string()
|
||||
substitute_string
|
||||
}
|
||||
} else {
|
||||
"?".to_string()
|
||||
substitute_string
|
||||
}
|
||||
} else {
|
||||
String::new()
|
||||
|
|
|
@ -2282,7 +2282,23 @@ fn test_ls_dangling_symlinks() {
|
|||
|
||||
#[test]
|
||||
#[cfg(feature = "feat_selinux")]
|
||||
fn test_ls_context() {
|
||||
fn test_ls_context1() {
|
||||
use selinux::{self, KernelSupport};
|
||||
if selinux::kernel_support() == KernelSupport::Unsupported {
|
||||
println!("test skipped: Kernel has no support for SElinux context",);
|
||||
return;
|
||||
}
|
||||
|
||||
let file = "test_ls_context_file";
|
||||
let expected = format!("unconfined_u:object_r:user_tmp_t:s0 {}\n", file);
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
at.touch(file);
|
||||
ucmd.args(&["-Z", file]).succeeds().stdout_is(expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "feat_selinux")]
|
||||
fn test_ls_context2() {
|
||||
use selinux::{self, KernelSupport};
|
||||
if selinux::kernel_support() == KernelSupport::Unsupported {
|
||||
println!("test skipped: Kernel has no support for SElinux context",);
|
||||
|
|
Loading…
Reference in a new issue