dotnet/wpf · error · ArgumentOutOfRangeException

SR.StreamLengthNegative

Error message

SR.StreamLengthNegative

What it means

CFStream.SetLength throws ArgumentOutOfRangeException with SR.StreamLengthNegative when newLength is negative. A stream cannot have a negative size, so the library rejects the value before calling the native IStream.SetSize. This is a direct parameter-contract check.

Solutions

  1. Validate the target length is >= 0 before calling SetLength
  2. Clamp: stream.SetLength(Math.Max(0, newSize));
  3. Check the value source (header/config) for corrupt or malicious data
  4. Catch ArgumentOutOfRangeException to flag bad size computation

Example fix

// before
cfStream.SetLength(currentSize - removedBytes);
// after
cfStream.SetLength(Math.Max(0, currentSize - removedBytes));
Defensive patterns

Strategy: validation

Validate before calling

if (newLength < 0) throw new ArgumentOutOfRangeException(nameof(newLength), "Length must be >= 0.");

Type guard

static bool IsValidStreamLength(long len) => len >= 0 && len <= int.MaxValue;

Try / catch

try { stream.SetLength(newLength); } catch (ArgumentOutOfRangeException ex) { /* clamp and retry */ }

Prevention

When it happens

Trigger: Calling SetLength(-1) or any negative value on a CFStream; computing the new size from arithmetic that underflows (e.g. currentSize - removedBytes where removedBytes > currentSize).

Common situations: Subtraction-based resize logic that doesn't account for actual stream length; untrusted size values parsed from file headers or config; integer overflow producing negative results.

Related errors


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

Appendix: source

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

        return seekPos;
    }

    /// <summary>
    /// See .NET Framework SDK under System.IO.Stream
    /// </summary>
    /// <param name="newLength">New length</param>
    public override void SetLength( long newLength )
    {
        CheckDisposedStatus();

        if (!CanWrite)
        {
            throw new NotSupportedException(SR.SetLengthNotSupported);
        }

        if( 0 > newLength )
        {
            throw new ArgumentOutOfRangeException(nameof(newLength),
                SR.StreamLengthNegative);
        }
        
        _safeIStream.SetSize( newLength );

        // updating the stream pointer if the stream has been truncated.
        if (newLength < this.Position)
            this.Position = newLength;
    }

    /// <summary>
    /// See .NET Framework SDK under System.IO.Stream
    /// </summary>
    /// <param name="buffer">Read data buffer</param>
    /// <param name="offset">Buffer start position</param>
    /// <param name="count">Number of bytes to read</param>
    /// <returns>Number of bytes actually read</returns>
    public override int Read( byte[] buffer, int offset, int count )

View on GitHub (pinned to 81131a70a4)