Skip to content

head: reset stale partial line state on reused buffers#11407

Merged
cakebaker merged 2 commits intouutils:mainfrom
can1357:head-reset-stale-partial-line-state-on-reused-buffers
Mar 27, 2026
Merged

head: reset stale partial line state on reused buffers#11407
cakebaker merged 2 commits intouutils:mainfrom
can1357:head-reset-stale-partial-line-state-on-reused-buffers

Conversation

@can1357
Copy link
Copy Markdown
Contributor

@can1357 can1357 commented Mar 18, 2026

uutils head -n -N on non-seekable input can leak one trailing line because TakeAllLinesBuffer.partial_line is reused across fills and can stay true after a later terminated chunk. GNU recomputes tail state from current bytes each read; this fix resets the flag in fill_buffer and adds a deterministic regression covering the non-seekable code path.

Reproduction Steps

t=$(mktemp -u)
mkfifo "$t"
{ exec 3>"$t"; printf 'A' >&3; sleep 0.05; printf '\nB\nC' >&3; sleep 0.05; printf 'D\n' >&3; exec 3>&-; } &
head -n -1 <"$t" | od -An -tx1 -v
wait
rm "$t"
# Expected (GNU): 41 0a 42 0a
# Actual (uutils): 41 0a 42 0a 43 44 0a

Impact

Pipelines that rely on head -n -N for tail elision on non-seekable streams can silently emit data that should be suppressed. This is a correctness issue.

@cakebaker cakebaker merged commit 97e69f0 into uutils:main Mar 27, 2026
162 of 163 checks passed
@cakebaker
Copy link
Copy Markdown
Contributor

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants