pola-rs/polars · error · std::io::Error
InvalidInput
InvalidInput
Error message
invalid seek to a negative or overflowing position
What it means
FixedSizeChunkedBytesCursor (polars-utils' Seek impl over sliced chunked bytes) rejects seeks whose resolved position is negative or overflows: for SeekFrom::End/Current, base_pos.checked_add_signed(offset) returned None. SeekFrom::Start is instead clamped to total_size, so only relative and end-relative seeks can fail.
Source
Thrown at crates/polars-utils/src/chunked_bytes_cursor.rs:128
impl<'a, T> std::io::Seek for FixedSizeChunkedBytesCursor<'a, T> {
fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
// Mostly copied from io::Cursor::seek().
use std::io::SeekFrom;
let (base_pos, offset) = match pos {
SeekFrom::Start(n) => {
self.position = usize::try_from(n).unwrap().min(self.total_size);
return Ok(self.position as u64);
},
SeekFrom::End(n) => (self.total_size as u64, n),
SeekFrom::Current(n) => (self.position as u64, n),
};
match base_pos.checked_add_signed(offset) {
Some(n) => {
self.position = usize::try_from(n).unwrap();
Ok(self.position as u64)
},
None => Err(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
"invalid seek to a negative or overflowing position",
)),
}
}
}
View on GitHub (pinned to df599052da)
Solutions
- Compute the target position with checked arithmetic and clamp it to 0..=len, then seek with SeekFrom::Start
- Treat offsets read from file headers as untrusted: range-check them and report corruption instead of seeking
- For 'end minus n' patterns, verify n <= total_size before seeking
- Prefer u64/i128 intermediate math when combining positions and signed deltas
Example fix
// before
let pos = header.footer_offset(); // may be garbage
cursor.seek(SeekFrom::Current(pos))?;
// after
let target: i128 = cursor.stream_position()? as i128 + pos as i128;
if !(0..=total_len as i128).contains(&target) {
return Err(corrupt_file_error());
}
cursor.seek(SeekFrom::Start(target as u64))?; Defensive patterns
Strategy: validation
Validate before calling
use std::io::{Seek, SeekFrom};
fn checked_seek(cursor: &mut impl Seek, from: SeekFrom, len: u64) -> std::io::Result<u64> {
let base = match from {
SeekFrom::Start(n) => n as i128,
SeekFrom::End(n) => len as i128 + n as i128,
SeekFrom::Current(n) => cursor.stream_position()? as i128 + n as i128,
};
if !(0..=len as i128).contains(&base) {
return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "seek out of range"));
}
cursor.seek(SeekFrom::Start(base as u64))
} Prevention
- Treat offsets parsed from file headers as untrusted; range-check before seeking
- Use SeekFrom::Start with a pre-clamped value instead of negative End/Current deltas
- Do offset math in i128 to dodge intermediate overflow
- For 'end minus n' seeks, verify n <= total size first
When it happens
Trigger: Seek(SeekFrom::End(-n)) or Seek(SeekFrom::Current(-n)) where n exceeds the current/end position (target below 0), or a huge positive offset overflowing u64 - typically readers computing positions from truncated or corrupt headers.
Common situations: Parsing corrupt/truncated IPC or parquet-like data where a stored offset is bogus; mixing up byte offsets with row indices; passing a negative delta from user-supplied seek parameters; off-by-one when seeking to a footer position.
Related errors
- cannot specify both `value` and `strategy`
- must specify either a fill `value` or `strategy`
- strategy {strategy!r} is not supported
- reinterpret requires exactly one of `signed` or `dtype` to b
- cannot specify both `n` and `fraction`
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/0becb1e9a4254398.
Report an issue: GitHub.