{"record":{"id":"6928ee7d1d2d2a54","repo":"dotnet/wpf","slug":"sr-invalidstringformat","errorCode":null,"errorMessage":"SR.InvalidStringFormat","messagePattern":"SR\\.InvalidStringFormat","errorType":"exception","errorClass":"FileFormatException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/RightsManagementEncryptionTransform.cs","lineNumber":1183,"sourceCode":"        /// file with a huge length prefix from making us allocate all our memory.\n        /// </param>\n        private static string\n        ReadLengthPrefixedString(\n            BinaryReader reader,\n            Encoding encoding,\n            int maxLength\n            )\n        {\n            Int32 length = reader.ReadInt32();\n            if (length > maxLength)\n            {\n                throw new FileFormatException(SR.Format(SR.ExcessiveLengthPrefix, length, maxLength));\n            }\n\n            byte[] bytes = reader.ReadBytes(length);\n            if (bytes.Length != length)\n            {\n                throw new FileFormatException(SR.InvalidStringFormat);\n            }\n\n            string s = encoding.GetString(bytes);\n\n            SkipDwordPadding(bytes.Length, reader);\n\n            return s;\n        }\n\n        /// <summary>\n        /// Skip past the DWORD padding bytes at the end of a string of the specified length.\n        /// </summary>\n        /// <param name=\"length\">\n        /// Length in bytes of the string that was read.\n        /// </param>\n        /// <param name=\"reader\">\n        /// Binary reader from which the string was read.\n        /// </param>","sourceCodeStart":1165,"sourceCodeEnd":1201,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/RightsManagementEncryptionTransform.cs#L1165-L1201","documentation":"FileFormatException thrown by ReadLengthPrefixedString when reader.ReadBytes(length) returns fewer bytes than the declared length prefix — the stream ended prematurely. It signals a truncated string payload inside a publish/use-license stream.","triggerScenarios":"Any call path through ReadLengthPrefixedString (LoadPublishLicense, LoadUserFromStream's base64UserName, LoadUseLicenseAndUserFromStream, LoadUseLicenseFromStream) where the length prefix promises N bytes but fewer than N remain in the stream.","commonSituations":"Truncated downloads or file copies; compound files damaged by disk errors; streams written by a buggy writer that under-counted the string length; reading a stream already positioned at/past its end.","solutions":["Verify the stream is fully intact (compare against expected size/checksum) before parsing","Re-acquire or regenerate the license data instead of parsing the damaged stream","Restore the compound file from backup","Check that the stream is not being consumed concurrently by another reader that advanced its position"],"exampleFix":"// before: assuming a complete stream\nvar license = LoadPublishLicense(packStream); // throws if truncated\n// after: check completeness first\nif (!packStream.CanRead || packStream.Length == 0)\n    throw new InvalidDataException(\"License stream is empty or unreadable.\");\nusing (var buffered = new MemoryStream(ReadAllBytes(packStream)))\n{\n    var license = LoadPublishLicense(buffered);\n}","handlingStrategy":"validation","validationCode":"bool StringFitsInStream(Stream s)\n{\n    if (s.Length - s.Position < sizeof(Int32)) return false;\n    long pos = s.Position;\n    using (var br = new BinaryReader(s, Encoding.UTF8, leaveOpen: true))\n    {\n        int len = br.ReadInt32();\n        bool ok = len >= 0 && s.Position + len <= s.Length;\n        s.Position = pos;\n        return ok;\n    }\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    var license = LoadPublishLicense(stream);\n}\ncatch (FileFormatException ex)\n{\n    logger.LogError(ex, \"License stream truncated: declared string length exceeds remaining bytes.\");\n    throw new InvalidDataException(\"Truncated license stream; re-acquire the license.\", ex);\n}","preventionTips":["Buffer streams fully into memory before parsing so truncation is detected up front","Verify file completeness (checksum) before opening compound files","Avoid reading streams concurrently from multiple consumers","Retry downloads of license-bearing files on incomplete transfer"],"tags":["file-format","truncated-data","length-prefix","wpf"],"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"}