QL-Win/QuickLook · error · PEImageParseException

DOS signature not found.

Error message

DOS signature not found.

What it means

First of the PE parsing guards in PEImage's constructor: if the byte array is shorter than 2 bytes there is no room even for the 'MZ' magic, so PEImageParseException(0, ...) is thrown. This is the earliest possible rejection — the file is too small to be any kind of executable.

Source

Thrown at QuickLook.Plugin/QuickLook.Plugin.PEViewer/PEImageParser/PEImage.cs:51

    /// <summary>
    /// Gets the optional header of this PE image file.
    /// </summary>
    public ImageOptionalHeader OptionalHeader { get; private set; }

    /// <summary>
    /// Gets the collection of section headers and data of this PE image file.
    /// </summary>
    public ImageSection[] Sections { get; private set; }

    private PEImage(byte[] originalImage)
    {
        OriginalImage = originalImage;

        using BinaryReader reader = new(new MemoryStream(OriginalImage));

        // MZ
        if (reader.BaseStream.Length < 2) throw new PEImageParseException(0, "DOS signature not found.");
        if (reader.ReadUInt16() != 0x5a4d) throw new PEImageParseException(0, "DOS header not found.");

        // DOS Header
        if (reader.BaseStream.Length - reader.BaseStream.Position < 64) throw new PEImageParseException((int)reader.BaseStream.Position, "DOS header incomplete.");

        DosHeader = new()
        {
            LastPageSize = reader.ReadUInt16(),
            PageCount = reader.ReadUInt16(),
            RelocationCount = reader.ReadUInt16(),
            HeaderSize = reader.ReadUInt16(),
            MinAlloc = reader.ReadUInt16(),
            MaxAlloc = reader.ReadUInt16(),
            InitialSS = reader.ReadUInt16(),
            InitialSP = reader.ReadUInt16(),
            Checksum = reader.ReadUInt16(),
            InitialIP = reader.ReadUInt16(),
            InitialCS = reader.ReadUInt16(),

View on GitHub (pinned to cb5d9c429c)

Solutions

  1. Pre-check the file length >= 64 (the DOS header) before constructing PEImage.
  2. Use a detector that reads the first 2 bytes ('MZ') before committing to PE parsing.
  3. Catch PEImageParseException at the plugin boundary and report 'not a valid executable'.
  4. Re-acquire the file if emptiness is unexpected.

Example fix

// before
if (reader.BaseStream.Length < 2) throw new PEImageParseException(0, "DOS signature not found.");

// after — caller-side size guard before parsing
if (new FileInfo(path).Length < 64) return null;
Defensive patterns

Strategy: validation

Validate before calling

if (!File.Exists(path) || new FileInfo(path).Length < 64) return; // too small to be a PE

Type guard

static bool CouldBePe(long len) => len >= 64;

Try / catch

try { var img = PEImage.FromFile(path); }
catch (PEImageParseException ex) when (ex.Message.Contains("DOS signature")) { /* not a PE */ }

Prevention

When it happens

Trigger: PEImage is constructed (e.g. via PEImage.FromFile or the byte[] constructor) with a buffer of length 0 or 1, so reader.BaseStream.Length < 2.

Common situations: An empty or near-empty file routed to the PE viewer; a 0/1-byte placeholder; a download that failed and produced an empty body; a file with a misleading .exe/.dll extension.

Related errors


AI-assisted analysis of QL-Win/QuickLook@cb5d9c429c (2026-08-13). Data as JSON: /api/errors/b6a58c6c229a2abb. Report an issue: GitHub.