From bc296455316a418ede9238f0b0a3745e261a0b46 Mon Sep 17 00:00:00 2001 From: Jeffrey Finkelstein Date: Mon, 17 May 2021 19:33:49 -0400 Subject: [PATCH] tail: fix off-by-one issue for +NUM args Fix an off-by-one issue for `tail -c +NUM` and `tail -n +NUM` command line options. --- src/uu/tail/src/tail.rs | 5 ++++- tests/by-util/test_tail.rs | 44 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/uu/tail/src/tail.rs b/src/uu/tail/src/tail.rs index 6dafee184..6af6d4b97 100644 --- a/src/uu/tail/src/tail.rs +++ b/src/uu/tail/src/tail.rs @@ -489,7 +489,10 @@ where E: fmt::Debug, { if beginning { - iter.skip(count as usize).map(|r| r.unwrap()).collect() + // GNU `tail` seems to index bytes and lines starting at 1, not + // at 0. It seems to treat `+0` and `+1` as the same thing. + let i = count.max(1) - 1; + iter.skip(i as usize).map(|r| r.unwrap()).collect() } else { RingBuffer::from_iter(iter.map(|r| r.unwrap()), count as usize).data } diff --git a/tests/by-util/test_tail.rs b/tests/by-util/test_tail.rs index 1c025cf4c..dddbb9c31 100644 --- a/tests/by-util/test_tail.rs +++ b/tests/by-util/test_tail.rs @@ -348,3 +348,47 @@ fn test_negative_indexing() { fn test_sleep_interval() { new_ucmd!().arg("-s").arg("10").arg(FOOBAR_TXT).succeeds(); } + + +/// Test for reading all but the first NUM bytes: `tail -c +3`. +#[test] +fn test_positive_bytes() { + new_ucmd!() + .args(&["-c", "+3"]) + .pipe_in("abcde") + .succeeds() + .stdout_is("cde"); +} + + +/// Test for reading all bytes, specified by `tail -c +0`. +#[test] +fn test_positive_zero_bytes() { + new_ucmd!() + .args(&["-c", "+0"]) + .pipe_in("abcde") + .succeeds() + .stdout_is("abcde"); +} + + +/// Test for reading all but the first NUM lines: `tail -n +3`. +#[test] +fn test_positive_lines() { + new_ucmd!() + .args(&["-n", "+3"]) + .pipe_in("a\nb\nc\nd\ne\n") + .succeeds() + .stdout_is("c\nd\ne\n"); +} + + +/// Test for reading all lines, specified by `tail -n +0`. +#[test] +fn test_positive_zero_lines() { + new_ucmd!() + .args(&["-n", "+0"]) + .pipe_in("a\nb\nc\nd\ne\n") + .succeeds() + .stdout_is("a\nb\nc\nd\ne\n"); +}