dotnet/wpf · error · FileFormatException

SR.Format(SR.ExcessiveLengthPrefix, length, maxLength)

Error message

SR.Format(SR.ExcessiveLengthPrefix, length, maxLength)

What it means

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.

Solutions

  1. Regenerate the compound file with the standard writer so length prefixes follow the expected schema
  2. Validate the length field against the documented maximum before parsing (reimplement the prefix check in a pre-read pass)
  3. Restore the file from a known-good backup or re-acquire the license/publish data
  4. Treat the input as untrusted: catch FileFormatException around license loading and fall back to re-acquiring licenses

Example fix

// before: trusting a length read from an untrusted stream
Int32 length = reader.ReadInt32();
byte[] bytes = reader.ReadBytes(length); // can allocate gigabytes / throw
// after: bound-check the prefix first
Int32 length = reader.ReadInt32();
if (length < 0 || length > MaxAllowedLength)
    throw new FileFormatException(SR.Format(SR.ExcessiveLengthPrefix, length, MaxAllowedLength));
byte[] bytes = reader.ReadBytes(length);
Defensive patterns

Strategy: validation

Validate before calling

bool HasSaneLengthPrefix(Stream s, int maxLength)
{
    if (s.Length - s.Position < sizeof(Int32)) return false;
    long pos = s.Position;
    using (var br = new BinaryReader(s, new byte[0].GetType() == null ? null : Encoding.UTF8, leaveOpen: true))
    {
        int len = br.ReadInt32();
        s.Position = pos;
        return len >= 0 && len <= maxLength && len <= s.Length - s.Position - sizeof(Int32);
    }
}

Try / catch

try
{
    var user = LoadUserFromStream(reader);
}
catch (FileFormatException ex)
{
    throw new InvalidDataException("Length prefix in license stream exceeds schema maximum; file is corrupt or hostile.", ex);
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/d467ac7d6c69e1cf. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/RightsManagementEncryptionTransform.cs:1177

        /// </param>
        /// <param name="encoding">
        /// Object that specifies how the string has been encoded.
        /// </param>
        /// <param name="maxLength">
        /// The maximum number of characters that the string can contain. This prevents a malformed
        /// file with a huge length prefix from making us allocate all our memory.
        /// </param>
        private static string
        ReadLengthPrefixedString(
            BinaryReader reader,
            Encoding encoding,
            int maxLength
            )
        {
            Int32 length = reader.ReadInt32();
            if (length > maxLength)
            {
                throw new FileFormatException(SR.Format(SR.ExcessiveLengthPrefix, length, maxLength));
            }

            byte[] bytes = reader.ReadBytes(length);
            if (bytes.Length != length)
            {
                throw new FileFormatException(SR.InvalidStringFormat);
            }

            string s = encoding.GetString(bytes);

            SkipDwordPadding(bytes.Length, reader);

            return s;
        }

        /// <summary>
        /// Skip past the DWORD padding bytes at the end of a string of the specified length.
        /// </summary>

View on GitHub (pinned to 81131a70a4)