{"record":{"id":"770aef0d968edd79","repo":"dotnet/wpf","slug":"read","errorCode":null,"errorMessage":"Read","messagePattern":"Read","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/IO/Packaging/UnsafeIndexingFilterStream.cs","lineNumber":110,"sourceCode":"            // Prepare location of return value and call the COM object.\n            int    bytesRead;\n            IntPtr pBytesRead = new IntPtr(&bytesRead);\n\n            // Prepare to restore position in case the read fails.\n            long positionBeforeReadAttempt = this.Position;\n\n            try \n            {\n                // Pin the array wrt GC while using an address in it.\n                fixed (byte *bufferPointer = &buffer[offset])\n                {\n                    _oleStream.Read(new IntPtr(bufferPointer), count, pBytesRead);\n                }\n            }\n            catch (COMException comException)\n            {\n                this.Position = positionBeforeReadAttempt;\n                throw new IOException(\"Read\", comException);\n            }\n            catch (IOException ioException)\n            {\n                this.Position = positionBeforeReadAttempt;\n                throw new IOException(\"Read\", ioException);\n            }\n            return bytesRead;\n        }\n\n        /// <summary>\n        /// Seek -unmanaged streams do not allow seeking beyond the end of the stream\n        /// and since we rely on the underlying stream to validate and return the seek\n        /// results, unlike managed streams where seeking beyond the end of the stream\n        /// is allowed we will get an exception.\n        /// </summary>\n        /// <param name=\"offset\">Offset in byte.</param>\n        /// <param name=\"origin\">Offset origin (start, current, or end).</param>\n        public override unsafe long Seek(long offset, SeekOrigin origin)","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/IO/Packaging/UnsafeIndexingFilterStream.cs#L92-L128","documentation":"UnsafeIndexingFilterStream.Read reads through an unmanaged IStream (_oleStream) exposed by a COM IFilter. If the underlying OLE stream throws COMException, or a nested IOException occurs, the stream restores Position to the pre-read value and rethrows as a bare IOException with message \"Read\" and the original exception as InnerException. The real cause is always in InnerException.","triggerScenarios":"Calling Stream.Read on an UnsafeIndexingFilterStream when the underlying _oleStream.Read COM call fails (corrupt or non-seekable source stream, filter error) or an inner IOException propagates.","commonSituations":"Indexing/searching a damaged or partially downloaded XPS/OPC package; the filter's stream fails mid-read; callers that inspect only ex.Message see the useless string \"Read\" and miss the COMException details.","solutions":["Inspect the InnerException (COMException) of the IOException for the actual HRESULT and failure reason.","Validate/repair the package file before opening the indexing filter stream.","Retry reading after the stream auto-rewinds Position, if the source is intermittently failing.","Catch IOException and fall back to reading the part via System.IO.Packaging APIs instead of the filter stream."],"exampleFix":"// before\nint n = filterStream.Read(buffer, 0, buffer.Length);\n// after\ntry\n{\n    int n = filterStream.Read(buffer, 0, buffer.Length);\n}\ncatch (IOException ex) when (ex.InnerException is COMException cex)\n{\n    // inspect cex.ErrorCode for the real HRESULT\n}","handlingStrategy":"try-catch","validationCode":"// before reading\nif (filterStream == null || !filterStream.CanRead)\n    throw new InvalidOperationException(\"Filter stream not readable\");","typeGuard":null,"tryCatchPattern":"try { int n = filterStream.Read(buffer, 0, count); }\ncatch (IOException ex)\n{\n    // Position was auto-restored; log ex.InnerException (often COMException with HRESULT)\n    throw new IOException(\"Indexing filter read failed\", ex);\n}","preventionTips":["Always read ex.InnerException to learn the real HRESULT/cause.","Verify the package file is valid and fully downloaded before indexing.","Keep the source stream open for the filter stream's whole lifetime.","Use the auto-restored Position to safely retry reads."],"tags":["io","stream","com","packaging","read-failure"],"backgroundTag":"file-read-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"}