{"record":{"id":"5ceb4de16112427f","repo":"QL-Win/QuickLook","slug":"offset-is-before-the-current-position-in-the-strea","errorCode":null,"errorMessage":"Offset is before the current position in the stream.","messagePattern":"Offset is before the current position in the stream\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"QuickLook.Plugin/QuickLook.Plugin.PEViewer/PEImageParser/ImageSection.cs","lineNumber":84,"sourceCode":"    /// </returns>\n    public static byte[] GetBytes(this byte[] array, int index, int count)\n    {\n        byte[] result = new byte[count];\n        Buffer.BlockCopy(array, index, result, 0, count);\n        return result;\n    }\n\n    public static byte[] GetBytes(this Stream stream, long index, int count)\n    {\n        byte[] buffer = new byte[count];\n\n        // Ensure the stream is at the correct position\n        long currentPosition = stream.Position;\n        long bytesToSkip = index - currentPosition;\n\n        if (bytesToSkip < 0)\n        {\n            throw new ArgumentException(\"Offset is before the current position in the stream.\");\n        }\n\n        // Skip bytes until reaching the target offset\n        while (bytesToSkip > 0)\n        {\n            int bytesSkipped = (int)Math.Min(bytesToSkip, int.MaxValue);\n            stream.Read(new byte[bytesSkipped], 0, bytesSkipped);\n            bytesToSkip -= bytesSkipped;\n        }\n\n        // Read the required number of bytes\n        int bytesRead = stream.Read(buffer, 0, count);\n        if (bytesRead < count)\n        {\n            throw new EndOfStreamException(\"The stream has fewer bytes available than requested.\");\n        }\n\n        return buffer;","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/QL-Win/QuickLook/blob/cb5d9c429c81d9796fac469da2a68efb5626946d/QuickLook.Plugin/QuickLook.Plugin.PEViewer/PEImageParser/ImageSection.cs#L66-L102","documentation":"Thrown by the Stream.GetBytes extension used by the PE parser: it computes bytesToSkip = index - stream.Position and requires this to be >= 0. A negative value means the requested `index` is behind the stream's current cursor, and because the method only supports forward skipping (it reads-and-discards), it throws ArgumentException rather than seeking.","triggerScenarios":"Calling GetBytes(stream, index, count) with an `index` smaller than stream.Position — e.g. requesting a section whose PointerToRawData is before where the cursor already advanced during header parsing, on a non-seekable or forward-only consumption.","commonSituations":"Parsing PE structures out of order (reading a later section then an earlier one) without rewinding; using a forward-only stream (network/decompressed) where Position only increases; an off-by-one or wrong offset computed for PointerToRawData.","solutions":["If the stream is seekable, set stream.Position = index before calling GetBytes instead of relying on the skip logic.","Read PE structures in file-offset order so the cursor only moves forward.","Buffer the whole image into a MemoryStream/byte[] and index randomly rather than streaming.","Catch ArgumentException and re-open the stream from the start for out-of-order access."],"exampleFix":"// before\nlong bytesToSkip = index - currentPosition;\nif (bytesToSkip < 0)\n    throw new ArgumentException(\"Offset is before the current position in the stream.\");\n\n// after — rewind when seekable\nif (index < stream.Position)\n{\n    if (stream.CanSeek) stream.Position = index;\n    else throw new ArgumentException(\"Offset is before the current position and stream is not seekable.\");\n}","handlingStrategy":"validation","validationCode":"if (index < stream.Position) {\n    if (stream.CanSeek) stream.Position = index;\n    else throw new ArgumentException(\"Cannot read backwards on a forward-only stream.\");\n}","typeGuard":"static bool CanReadAt(Stream s, long index) => index >= s.Position || s.CanSeek;","tryCatchPattern":"try { bytes = stream.GetBytes(index, count); }\ncatch (ArgumentException) { stream.Position = index; bytes = stream.GetBytes(index, count); }","preventionTips":["Read PE structures in ascending file-offset order on forward-only streams.","Prefer seekable MemoryStream/byte[] for random section access.","Set stream.Position explicitly when CanSeek is true."],"tags":["pe","stream","offset","seekable","binary-parsing"],"backgroundTag":null,"analyzedSha":"cb5d9c429c81d9796fac469da2a68efb5626946d","analyzedAt":"2026-08-13T11:51:01.370Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}