{"record":{"id":"143a396364ddf5c3","repo":"dotnet/wpf","slug":"sr-cfrcorruptstgfollowstm","errorCode":null,"errorMessage":"SR.CFRCorruptStgFollowStm","messagePattern":"SR\\.CFRCorruptStgFollowStm","errorType":"exception","errorClass":"FileFormatException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/CompoundFileReference.cs","lineNumber":190,"sourceCode":"            // type is encountered\n            StringCollection storageList = null;\n            String streamName = null;\n\n            // loop through the entries - accumulating strings until we know what kind of object\n            // we ultimately need\n            int byteLength;     // reusable\n            while (entryCount > 0)\n            {\n                // first Int32 tells us what kind of component this entry represents\n                RefComponentType refType = (RefComponentType)reader.ReadInt32();\n                bytesRead += ContainerUtilities.Int32Size;\n\n                switch (refType)\n                {\n                    case RefComponentType.Storage:\n                    {\n                        if (streamName != null)\n                            throw new FileFormatException(\n                                SR.CFRCorruptStgFollowStm);\n\n                        if (storageList == null)\n                            storageList = new StringCollection();\n\n                        String str = ContainerUtilities.ReadByteLengthPrefixedDWordPaddedUnicodeString(reader, out byteLength);\n                        bytesRead += byteLength;\n                        storageList.Add(str);\n} break;\n                    case RefComponentType.Stream:\n                    {\n                        if (streamName != null)\n                            throw new FileFormatException(\n                                SR.CFRCorruptMultiStream);\n\n                        streamName = ContainerUtilities.ReadByteLengthPrefixedDWordPaddedUnicodeString(reader, out byteLength);\n                        bytesRead += byteLength;\n                    } break;","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/CompoundFileReference.cs#L172-L208","documentation":"While Load walks the reference's path segments, storage and stream components must be ordered storages-first, stream-last. A Storage entry appearing after a stream name means the path is malformed (nothing can live under a stream), so Load throws FileFormatException(SR.CFRCorruptStgFollowStm).","triggerScenarios":"Load reads a RefComponentType.Storage entry after already having read a stream name — i.e. the serialized path looks like \\storage\\stream\\storage. Caused by corrupt data or a writer emitting entries in the wrong order.","commonSituations":"Hand-crafted or fuzzed compound files; writers that serialize path segments out of order; byte-level corruption reordering records; mixed-version writer/reader format drift.","solutions":["Regenerate the package from its source — the serialized path is structurally invalid.","Check the producing writer's reference serialization for storage/stream ordering bugs.","If parsing third-party files, reject them up front with your own structural validation.","Diff the record bytes against a known-good reference to find where ordering broke."],"exampleFix":"// before: blind deserialization of untrusted references\nvar r = CompoundFileReference.Load(binaryReader);\n\n// after: pre-validate ordering of path components\nValidateReferencePathOrder(rawBytes); // storage... then stream last\nvar r = CompoundFileReference.Load(binaryReader);","handlingStrategy":"validation","validationCode":"bool PathOrderIsValid(IList<(bool isStorage)> segs) { bool sawStream = false; foreach (var s in segs) { if (!s.isStorage) sawStream = true; else if (sawStream) return false; } return true; }","typeGuard":null,"tryCatchPattern":"try { var r = CompoundFileReference.Load(reader); } catch (FileFormatException) { RejectMalformedReference(source); }","preventionTips":["Ensure writers serialize storages before stream names","Structurally validate third-party compound files before load","Fuzz-test your own writer's reference serialization"],"tags":["file-format","corruption","deserialization","wpf"],"backgroundTag":"schema-validation-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"}