{"record":{"id":"0becb1e9a4254398","repo":"pola-rs/polars","slug":"invalidinput","errorCode":"InvalidInput","errorMessage":"invalid seek to a negative or overflowing position","messagePattern":"invalid seek to a negative or overflowing position","errorType":"exception","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"crates/polars-utils/src/chunked_bytes_cursor.rs","lineNumber":128,"sourceCode":"impl<'a, T> std::io::Seek for FixedSizeChunkedBytesCursor<'a, T> {\n    fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {\n        // Mostly copied from io::Cursor::seek().\n        use std::io::SeekFrom;\n\n        let (base_pos, offset) = match pos {\n            SeekFrom::Start(n) => {\n                self.position = usize::try_from(n).unwrap().min(self.total_size);\n                return Ok(self.position as u64);\n            },\n            SeekFrom::End(n) => (self.total_size as u64, n),\n            SeekFrom::Current(n) => (self.position as u64, n),\n        };\n        match base_pos.checked_add_signed(offset) {\n            Some(n) => {\n                self.position = usize::try_from(n).unwrap();\n                Ok(self.position as u64)\n            },\n            None => Err(std::io::Error::new(\n                std::io::ErrorKind::InvalidInput,\n                \"invalid seek to a negative or overflowing position\",\n            )),\n        }\n    }\n}\n","sourceCodeStart":110,"sourceCodeEnd":135,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/crates/polars-utils/src/chunked_bytes_cursor.rs#L110-L135","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nlet pos = header.footer_offset(); // may be garbage\ncursor.seek(SeekFrom::Current(pos))?;\n\n// after\nlet target: i128 = cursor.stream_position()? as i128 + pos as i128;\nif !(0..=total_len as i128).contains(&target) {\n    return Err(corrupt_file_error());\n}\ncursor.seek(SeekFrom::Start(target as u64))?;","handlingStrategy":"validation","validationCode":"use std::io::{Seek, SeekFrom};\n\nfn checked_seek(cursor: &mut impl Seek, from: SeekFrom, len: u64) -> std::io::Result<u64> {\n    let base = match from {\n        SeekFrom::Start(n) => n as i128,\n        SeekFrom::End(n) => len as i128 + n as i128,\n        SeekFrom::Current(n) => cursor.stream_position()? as i128 + n as i128,\n    };\n    if !(0..=len as i128).contains(&base) {\n        return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, \"seek out of range\"));\n    }\n    cursor.seek(SeekFrom::Start(base as u64))\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["rust","polars","seek","cursor","validation"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}