Why this matters
The bug. Plain read line does two surprising things. First, it interprets \ as an escape, so a line containing C:\Users\me becomes C:Usersme. Second, when EOF is reached *without* a trailing newline, read returns failure — and the loop body never runs for that final line.
The fix. IFS= read -r line || [ -n "$line" ] is the canonical safe form: -r disables backslash escapes, IFS= preserves leading/trailing whitespace, and the || [ -n "$line" ] check catches the no-newline final line.
Bash hygiene. shellcheck flags missing -r as SC2162 — keep it on in CI.
Review heuristic
When a comparison involves <, <=, >, >=, or -1, work the boundary case by hand: what happens with zero items? One item? n+1 items? Pagination, buffer length, and recursion are the three places where the bug is most likely.
External reference: CWE-193: Off-by-one Error.