diff --git a/src/uu/tail/src/tail.rs b/src/uu/tail/src/tail.rs index ee70f7ef188..6f169d3f4b5 100644 --- a/src/uu/tail/src/tail.rs +++ b/src/uu/tail/src/tail.rs @@ -1411,7 +1411,9 @@ fn bounded_tail(file: &mut File, settings: &Settings) { file.seek(SeekFrom::Start(i as u64)).unwrap(); } (FilterMode::Bytes(count), false) => { - file.seek(SeekFrom::End(-(*count as i64))).unwrap(); + let len = file.seek(SeekFrom::End(0)).unwrap(); + file.seek(SeekFrom::End(-((*count).min(len) as i64))) + .unwrap(); } (FilterMode::Bytes(count), true) => { // GNU `tail` seems to index bytes and lines starting at 1, not diff --git a/tests/by-util/test_tail.rs b/tests/by-util/test_tail.rs index d4755a48832..6afd55f51d7 100644 --- a/tests/by-util/test_tail.rs +++ b/tests/by-util/test_tail.rs @@ -2435,3 +2435,23 @@ fn test_illegal_seek() { ); assert_eq!(p.wait().unwrap().code().unwrap(), 1); } + +#[test] +fn test_seek_bytes_backward_outside_file() { + new_ucmd!() + .arg("-c") + .arg("100") + .arg(FOOBAR_TXT) + .run() + .stdout_is_fixture(FOOBAR_TXT); +} + +#[test] +fn test_seek_bytes_forward_outside_file() { + new_ucmd!() + .arg("-c") + .arg("+100") + .arg(FOOBAR_TXT) + .run() + .stdout_is(""); +}