NationalSecurityAgency/ghidra · error · IOException
pos cannot be less than zero
Error message
pos cannot be less than zero
What it means
GRandomAccessFile.seek(long pos) calls checkOpen() then explicitly rejects pos < 0 with this IOException, rather than letting the underlying RandomAccessFile.seek throw. A negative position is nonsensical for a file offset, so it indicates a computed offset went wrong upstream (underflow, bad arithmetic, endianness).
Source
Thrown at GPL/DMG/src/dmg/java/mobiledevices/dmg/ghidra/GRandomAccessFile.java:133
/**
* Sets the file-pointer offset, measured from the beginning of this
* file, at which the next read or write occurs. The offset may be
* set beyond the end of the file. Setting the offset beyond the end
* of the file does not change the file length. The file length will
* change only by writing after the offset has been set beyond the end
* of the file.
* @param pos the offset position, measured in bytes from the
* beginning of the file, at which to set the file
* pointer.
* @throws IOException
* @exception IOException if <code>pos</code> is less than
* <code>0</code> or if an I/O error occurs.
*/
public void seek(long pos) throws IOException {
checkOpen();
if (pos < 0) {
throw new IOException("pos cannot be less than zero");
}
if (pos < bufferFileStartIndex || pos >= bufferFileStartIndex + BUFFER_SIZE) {
// check if the last buffer contained it, and swap in if necessary
swapInLast();
if (pos < bufferFileStartIndex || pos >= bufferFileStartIndex + BUFFER_SIZE) {
// not in either, gotta get a new one
buffer = EMPTY;
bufferOffset = 0;
bufferFileStartIndex = pos;
}
}
bufferOffset = pos - bufferFileStartIndex;
}
/**
* This method reads a byte from the file, starting from the current file pointer.
* <p>View on GitHub (pinned to d5f144c24d)
Solutions
- Log pos and its components before seek to identify which offset went negative.
- Verify the offset fields feeding pos are read with the correct width and endianness.
- Bounds-check pos against [0, length()) before seeking.
- Confirm the parsed structure providing the offset is intact (re-check the parent parse).
Example fix
// before
raf.seek(base + relative);
// after
long pos = base + relative;
if (pos < 0 || pos > raf.length()) {
throw new IOException("Bad seek target " + pos + " (base=" + base + ", rel=" + relative + ")");
}
raf.seek(pos); Defensive patterns
Strategy: validation
Validate before calling
if (pos < 0) {
throw new IOException("Refusing negative seek: " + pos + " (computed offset is corrupt)");
}
if (pos > raf.length()) {
throw new IOException("Seek target " + pos + " past EOF " + raf.length());
}
raf.seek(pos); Type guard
private static boolean isSeekable(long pos, long fileLen) {
return pos >= 0 && pos <= fileLen;
} Try / catch
try {
raf.seek(pos);
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().contains("less than zero")) {
throw new IOException("Negative seek computed (likely corrupt offset field)", e);
}
throw e;
} Prevention
- Bounds-check computed offsets against [0, length()] before seeking.
- Verify offset fields use correct endianness and width when computing positions.
- Log the components of a computed offset so underflow is diagnosable.
When it happens
Trigger: Calling seek(pos) where pos is negative. pos is usually computed from parsed offsets (base + relative, or a record's start); a corrupt/wrong relative offset or an arithmetic underflow can drive it below zero.
Common situations: A parsed offset field read with wrong endianness yielding a huge value that wraps negative when narrowed or combined; subtracting a base offset that exceeds the position; truncated input where an offset field is missing (0) combined with a negative adjustment; off-by-one in computing a record's start.
Related errors
- Invalid number of elements specified: {}
- Bad nodeSize: {}
- Unable to read {} bytes
- No system partitions found. Perhaps the decryption failed?
- GhidraRandomAccessFile is closed
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/edc538be28fa4548.
Report an issue: GitHub.