dotnet/wpf · error · InvalidOperationException

Cannot initialize compressor.

Error message

Cannot initialize compressor.

What it means

The Compressor constructor validates the seed data buffer (data must be non-null and exactly `size` bytes) and throws 'Cannot initialize compressor.' otherwise. This deliberate, low-information message avoids revealing details attackers could exploit in the native ISF compressor.

Solutions

  1. Ensure the byte[] passed to the compressor constructor matches the declared size exactly
  2. Re-extract the compressor state from the source ISF stream; the blob is likely truncated
  3. Catch InvalidOperationException during ISF load and treat the file as corrupt rather than retrying with modified sizes

Example fix

// before
new Compressor(stateBytes, declaredSize); // throws if stateBytes.Length != declaredSize
// after
if (stateBytes != null && stateBytes.Length == declaredSize)
    new Compressor(stateBytes, declaredSize);
Defensive patterns

Strategy: validation

Validate before calling

if (data == null || data.Length != size) throw new InvalidDataException("compressor state size mismatch");

Type guard

bool IsValidCompressorState(byte[] d, int size) => d != null && d.Length == size;

Try / catch

try { InitCompressor(state, size); } catch (InvalidOperationException) { RecreateCompressor(); }

Prevention

When it happens

Trigger: Constructing the internal Compress/Compressor with a data buffer whose length does not match the declared size, or with null data, before IsfLoadCompressor is invoked.

Common situations: Corrupted compressor-state blobs loaded from disk/clipboard; mismatched size constants after format changes; fuzzing or malicious ISF inputs.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/9596f08d53d94f7d. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/InkSerializedFormat/Compress.cs:35

        private MS.Win32.Penimc.CompressorSafeHandle _compressorHandle;

        /// <summary>
        /// Compressor constructor.  This is called by our ISF decompression
        /// after reading the ISF header that indicates which type of compression
        /// was performed on the ISF when it was being compressed.
        /// </summary>
        /// <param name="data">a byte[] specifying the compressor used to compress the ISF being decompressed</param>
        /// <param name="size">expected initially to be the length of data, it IsfLoadCompressor sets it to the 
        ///                    length of the header that is read.  They should always match, but in cases where they 
        ///                    don't, we immediately fail</param>
        internal Compressor(byte[] data, ref uint size)
        {
            if (data == null || data.Length != size)
            {
                //we don't raise any information that could be used to attack our ISF code
                //a simple 'ISF Operation Failed' is sufficient since the user can't do 
                //anything to fix bogus ISF
                throw new InvalidOperationException(StrokeCollectionSerializer.ISFDebugMessage(SR.InitializingCompressorFailed));
            }
            
            _compressorHandle = MS.Win32.Penimc.UnsafeNativeMethods.IsfLoadCompressor(data, ref size);
            if (_compressorHandle.IsInvalid)
            {
                //we don't raise any information that could be used to attack our ISF code
                //a simple 'ISF Operation Failed' is sufficient since the user can't do 
                //anything to fix bogus ISF
                throw new InvalidOperationException(StrokeCollectionSerializer.ISFDebugMessage(SR.InitializingCompressorFailed));
            }
        }
        /// <summary>
        /// DecompressPacketData - take a byte[] or a subset of a byte[] and decompresses it into 
        ///     an int[] of packet data (for example, x's in a Stroke)
        /// </summary>
        /// <param name="compressor">
        ///     The compressor used to decompress this byte[] of packet data (for example, x's in a Stroke)
        ///     Can be null

View on GitHub (pinned to 81131a70a4)