{"record":{"id":"d467ac7d6c69e1cf","repo":"dotnet/wpf","slug":"sr-format-sr-excessivelengthprefix-length-maxlength","errorCode":null,"errorMessage":"SR.Format(SR.ExcessiveLengthPrefix, length, maxLength)","messagePattern":"SR\\.Format\\(SR\\.ExcessiveLengthPrefix, length, maxLength\\)","errorType":"exception","errorClass":"FileFormatException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/RightsManagementEncryptionTransform.cs","lineNumber":1177,"sourceCode":"        /// </param>\n        /// <param name=\"encoding\">\n        /// Object that specifies how the string has been encoded.\n        /// </param>\n        /// <param name=\"maxLength\">\n        /// The maximum number of characters that the string can contain. This prevents a malformed\n        /// 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>","sourceCodeStart":1159,"sourceCodeEnd":1195,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/RightsManagementEncryptionTransform.cs#L1159-L1195","documentation":"FileFormatException thrown by ReadLengthPrefixedString when the Int32 length prefix read from the stream exceeds the caller-supplied maxLength. This guards against absurd or malicious length values in compound-file strings (user names, license text) and aborts parsing immediately rather than attempting a huge ReadBytes.","triggerScenarios":"Reading a length-prefixed string from a publish/use-license stream where the stored length is greater than the schema maximum (e.g. UserNameLengthMax for the base64 user name in LoadUserFromStream, or the publish-license maximum in LoadPublishLicense).","commonSituations":"Corrupted or maliciously crafted compound files; streams written by incompatible tool versions using a different length encoding; random bytes interpreted as a length after a prior parse desynchronized.","solutions":["Regenerate the compound file with the standard writer so length prefixes follow the expected schema","Validate the length field against the documented maximum before parsing (reimplement the prefix check in a pre-read pass)","Restore the file from a known-good backup or re-acquire the license/publish data","Treat the input as untrusted: catch FileFormatException around license loading and fall back to re-acquiring licenses"],"exampleFix":"// before: trusting a length read from an untrusted stream\nInt32 length = reader.ReadInt32();\nbyte[] bytes = reader.ReadBytes(length); // can allocate gigabytes / throw\n// after: bound-check the prefix first\nInt32 length = reader.ReadInt32();\nif (length < 0 || length > MaxAllowedLength)\n    throw new FileFormatException(SR.Format(SR.ExcessiveLengthPrefix, length, MaxAllowedLength));\nbyte[] bytes = reader.ReadBytes(length);","handlingStrategy":"validation","validationCode":"bool HasSaneLengthPrefix(Stream s, int maxLength)\n{\n    if (s.Length - s.Position < sizeof(Int32)) return false;\n    long pos = s.Position;\n    using (var br = new BinaryReader(s, new byte[0].GetType() == null ? null : Encoding.UTF8, leaveOpen: true))\n    {\n        int len = br.ReadInt32();\n        s.Position = pos;\n        return len >= 0 && len <= maxLength && len <= s.Length - s.Position - sizeof(Int32);\n    }\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    var user = LoadUserFromStream(reader);\n}\ncatch (FileFormatException ex)\n{\n    throw new InvalidDataException(\"Length prefix in license stream exceeds schema maximum; file is corrupt or hostile.\", ex);\n}","preventionTips":["Treat compound-file contents as untrusted input; validate all length fields before ReadBytes","Only consume streams produced by the standard writer","Scan/validate files from untrusted sources before parsing","Keep a checksum of original files to detect tampering"],"tags":["file-format","malformed-input","length-prefix","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"}