mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
parent
553f70b06a
commit
22fbf16b2c
2 changed files with 74 additions and 10 deletions
|
@ -6,7 +6,7 @@
|
||||||
// For the full copyright and license information, please view the LICENSE
|
// For the full copyright and license information, please view the LICENSE
|
||||||
// file that was distributed with this source code.
|
// file that was distributed with this source code.
|
||||||
|
|
||||||
// spell-checker:ignore (vars) FiletestOp StrlenOp
|
// spell-checker:ignore (vars) egid euid FiletestOp StrlenOp
|
||||||
|
|
||||||
mod parser;
|
mod parser;
|
||||||
|
|
||||||
|
@ -96,8 +96,10 @@ fn eval(stack: &mut Vec<Symbol>) -> Result<bool, String> {
|
||||||
"-e" => path(&f, PathCondition::Exists),
|
"-e" => path(&f, PathCondition::Exists),
|
||||||
"-f" => path(&f, PathCondition::Regular),
|
"-f" => path(&f, PathCondition::Regular),
|
||||||
"-g" => path(&f, PathCondition::GroupIdFlag),
|
"-g" => path(&f, PathCondition::GroupIdFlag),
|
||||||
|
"-G" => path(&f, PathCondition::GroupOwns),
|
||||||
"-h" => path(&f, PathCondition::SymLink),
|
"-h" => path(&f, PathCondition::SymLink),
|
||||||
"-L" => path(&f, PathCondition::SymLink),
|
"-L" => path(&f, PathCondition::SymLink),
|
||||||
|
"-O" => path(&f, PathCondition::UserOwns),
|
||||||
"-p" => path(&f, PathCondition::Fifo),
|
"-p" => path(&f, PathCondition::Fifo),
|
||||||
"-r" => path(&f, PathCondition::Readable),
|
"-r" => path(&f, PathCondition::Readable),
|
||||||
"-S" => path(&f, PathCondition::Socket),
|
"-S" => path(&f, PathCondition::Socket),
|
||||||
|
@ -166,7 +168,9 @@ enum PathCondition {
|
||||||
Exists,
|
Exists,
|
||||||
Regular,
|
Regular,
|
||||||
GroupIdFlag,
|
GroupIdFlag,
|
||||||
|
GroupOwns,
|
||||||
SymLink,
|
SymLink,
|
||||||
|
UserOwns,
|
||||||
Fifo,
|
Fifo,
|
||||||
Readable,
|
Readable,
|
||||||
Socket,
|
Socket,
|
||||||
|
@ -190,18 +194,28 @@ fn path(path: &OsStr, condition: PathCondition) -> bool {
|
||||||
Execute = 0o1,
|
Execute = 0o1,
|
||||||
}
|
}
|
||||||
|
|
||||||
let perm = |metadata: Metadata, p: Permission| {
|
let geteuid = || {
|
||||||
#[cfg(not(target_os = "redox"))]
|
#[cfg(not(target_os = "redox"))]
|
||||||
let (uid, gid) = unsafe { (libc::getuid(), libc::getgid()) };
|
let euid = unsafe { libc::geteuid() };
|
||||||
#[cfg(target_os = "redox")]
|
#[cfg(target_os = "redox")]
|
||||||
let (uid, gid) = (
|
let euid = syscall::geteuid().unwrap() as u32;
|
||||||
syscall::getuid().unwrap() as u32,
|
|
||||||
syscall::getgid().unwrap() as u32,
|
|
||||||
);
|
|
||||||
|
|
||||||
if uid == metadata.uid() {
|
euid
|
||||||
|
};
|
||||||
|
|
||||||
|
let getegid = || {
|
||||||
|
#[cfg(not(target_os = "redox"))]
|
||||||
|
let egid = unsafe { libc::getegid() };
|
||||||
|
#[cfg(target_os = "redox")]
|
||||||
|
let egid = syscall::getegid().unwrap() as u32;
|
||||||
|
|
||||||
|
egid
|
||||||
|
};
|
||||||
|
|
||||||
|
let perm = |metadata: Metadata, p: Permission| {
|
||||||
|
if geteuid() == metadata.uid() {
|
||||||
metadata.mode() & ((p as u32) << 6) != 0
|
metadata.mode() & ((p as u32) << 6) != 0
|
||||||
} else if gid == metadata.gid() {
|
} else if getegid() == metadata.gid() {
|
||||||
metadata.mode() & ((p as u32) << 3) != 0
|
metadata.mode() & ((p as u32) << 3) != 0
|
||||||
} else {
|
} else {
|
||||||
metadata.mode() & (p as u32) != 0
|
metadata.mode() & (p as u32) != 0
|
||||||
|
@ -230,7 +244,9 @@ fn path(path: &OsStr, condition: PathCondition) -> bool {
|
||||||
PathCondition::Exists => true,
|
PathCondition::Exists => true,
|
||||||
PathCondition::Regular => file_type.is_file(),
|
PathCondition::Regular => file_type.is_file(),
|
||||||
PathCondition::GroupIdFlag => metadata.mode() & S_ISGID != 0,
|
PathCondition::GroupIdFlag => metadata.mode() & S_ISGID != 0,
|
||||||
|
PathCondition::GroupOwns => metadata.gid() == getegid(),
|
||||||
PathCondition::SymLink => metadata.file_type().is_symlink(),
|
PathCondition::SymLink => metadata.file_type().is_symlink(),
|
||||||
|
PathCondition::UserOwns => metadata.uid() == geteuid(),
|
||||||
PathCondition::Fifo => file_type.is_fifo(),
|
PathCondition::Fifo => file_type.is_fifo(),
|
||||||
PathCondition::Readable => perm(metadata, Permission::Read),
|
PathCondition::Readable => perm(metadata, Permission::Read),
|
||||||
PathCondition::Socket => file_type.is_socket(),
|
PathCondition::Socket => file_type.is_socket(),
|
||||||
|
@ -257,7 +273,9 @@ fn path(path: &OsStr, condition: PathCondition) -> bool {
|
||||||
PathCondition::Exists => true,
|
PathCondition::Exists => true,
|
||||||
PathCondition::Regular => stat.is_file(),
|
PathCondition::Regular => stat.is_file(),
|
||||||
PathCondition::GroupIdFlag => false,
|
PathCondition::GroupIdFlag => false,
|
||||||
|
PathCondition::GroupOwns => unimplemented!(),
|
||||||
PathCondition::SymLink => false,
|
PathCondition::SymLink => false,
|
||||||
|
PathCondition::UserOwns => unimplemented!(),
|
||||||
PathCondition::Fifo => false,
|
PathCondition::Fifo => false,
|
||||||
PathCondition::Readable => false, // TODO
|
PathCondition::Readable => false, // TODO
|
||||||
PathCondition::Socket => false,
|
PathCondition::Socket => false,
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// file that was distributed with this source code.
|
// file that was distributed with this source code.
|
||||||
//
|
//
|
||||||
|
|
||||||
// spell-checker:ignore (words) pseudofloat
|
// spell-checker:ignore (words) egid euid pseudofloat
|
||||||
|
|
||||||
use crate::common::util::*;
|
use crate::common::util::*;
|
||||||
|
|
||||||
|
@ -476,6 +476,52 @@ fn test_nonexistent_file_is_not_symlink() {
|
||||||
.succeeds();
|
.succeeds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
fn test_file_owned_by_euid() {
|
||||||
|
new_ucmd!().args(&["-O", "regular_file"]).succeeds();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
fn test_nonexistent_file_not_owned_by_euid() {
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-O", "nonexistent_file"])
|
||||||
|
.run()
|
||||||
|
.status_code(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(all(not(windows), not(target_os = "freebsd")))]
|
||||||
|
fn test_file_not_owned_by_euid() {
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-f", "/bin/sh", "-a", "!", "-O", "/bin/sh"])
|
||||||
|
.succeeds();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
fn test_file_owned_by_egid() {
|
||||||
|
new_ucmd!().args(&["-G", "regular_file"]).succeeds();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
fn test_nonexistent_file_not_owned_by_egid() {
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-G", "nonexistent_file"])
|
||||||
|
.run()
|
||||||
|
.status_code(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(all(not(windows), not(target_os = "freebsd")))]
|
||||||
|
fn test_file_not_owned_by_egid() {
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-f", "/bin/sh", "-a", "!", "-G", "/bin/sh"])
|
||||||
|
.succeeds();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_op_precedence_and_or_1() {
|
fn test_op_precedence_and_or_1() {
|
||||||
new_ucmd!().args(&[" ", "-o", "", "-a", ""]).succeeds();
|
new_ucmd!().args(&[" ", "-o", "", "-a", ""]).succeeds();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue