{"record":{"id":"9596f08d53d94f7d","repo":"dotnet/wpf","slug":"cannot-initialize-compressor","errorCode":null,"errorMessage":"Cannot initialize compressor.","messagePattern":"Cannot initialize compressor\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/InkSerializedFormat/Compress.cs","lineNumber":35,"sourceCode":"        private MS.Win32.Penimc.CompressorSafeHandle _compressorHandle;\n\n        /// <summary>\n        /// Compressor constructor.  This is called by our ISF decompression\n        /// after reading the ISF header that indicates which type of compression\n        /// was performed on the ISF when it was being compressed.\n        /// </summary>\n        /// <param name=\"data\">a byte[] specifying the compressor used to compress the ISF being decompressed</param>\n        /// <param name=\"size\">expected initially to be the length of data, it IsfLoadCompressor sets it to the \n        ///                    length of the header that is read.  They should always match, but in cases where they \n        ///                    don't, we immediately fail</param>\n        internal Compressor(byte[] data, ref uint size)\n        {\n            if (data == null || data.Length != size)\n            {\n                //we don't raise any information that could be used to attack our ISF code\n                //a simple 'ISF Operation Failed' is sufficient since the user can't do \n                //anything to fix bogus ISF\n                throw new InvalidOperationException(StrokeCollectionSerializer.ISFDebugMessage(SR.InitializingCompressorFailed));\n            }\n            \n            _compressorHandle = MS.Win32.Penimc.UnsafeNativeMethods.IsfLoadCompressor(data, ref size);\n            if (_compressorHandle.IsInvalid)\n            {\n                //we don't raise any information that could be used to attack our ISF code\n                //a simple 'ISF Operation Failed' is sufficient since the user can't do \n                //anything to fix bogus ISF\n                throw new InvalidOperationException(StrokeCollectionSerializer.ISFDebugMessage(SR.InitializingCompressorFailed));\n            }\n        }\n        /// <summary>\n        /// DecompressPacketData - take a byte[] or a subset of a byte[] and decompresses it into \n        ///     an int[] of packet data (for example, x's in a Stroke)\n        /// </summary>\n        /// <param name=\"compressor\">\n        ///     The compressor used to decompress this byte[] of packet data (for example, x's in a Stroke)\n        ///     Can be null","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/InkSerializedFormat/Compress.cs#L17-L53","documentation":"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.","triggerScenarios":"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.","commonSituations":"Corrupted compressor-state blobs loaded from disk/clipboard; mismatched size constants after format changes; fuzzing or malicious ISF inputs.","solutions":["Ensure the byte[] passed to the compressor constructor matches the declared size exactly","Re-extract the compressor state from the source ISF stream; the blob is likely truncated","Catch InvalidOperationException during ISF load and treat the file as corrupt rather than retrying with modified sizes"],"exampleFix":"// before\nnew Compressor(stateBytes, declaredSize); // throws if stateBytes.Length != declaredSize\n// after\nif (stateBytes != null && stateBytes.Length == declaredSize)\n    new Compressor(stateBytes, declaredSize);","handlingStrategy":"validation","validationCode":"if (data == null || data.Length != size) throw new InvalidDataException(\"compressor state size mismatch\");","typeGuard":"bool IsValidCompressorState(byte[] d, int size) => d != null && d.Length == size;","tryCatchPattern":"try { InitCompressor(state, size); } catch (InvalidOperationException) { RecreateCompressor(); }","preventionTips":["Persist the declared size with the compressor blob and check equality","Treat compressor state as opaque; never transform it","Include compressor state in integrity checks"],"tags":["wpf","ink","isf","initialization"],"backgroundTag":"module-init-failed","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}