{"record":{"id":"17985257b9dd0300","repo":"dotnet/wpf","slug":"sr-streamlengthnegative","errorCode":null,"errorMessage":"SR.StreamLengthNegative","messagePattern":"SR\\.StreamLengthNegative","errorType":"exception","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/CFStream.cs","lineNumber":197,"sourceCode":"        return seekPos;\n    }\n\n    /// <summary>\n    /// See .NET Framework SDK under System.IO.Stream\n    /// </summary>\n    /// <param name=\"newLength\">New length</param>\n    public override void SetLength( long newLength )\n    {\n        CheckDisposedStatus();\n\n        if (!CanWrite)\n        {\n            throw new NotSupportedException(SR.SetLengthNotSupported);\n        }\n\n        if( 0 > newLength )\n        {\n            throw new ArgumentOutOfRangeException(nameof(newLength),\n                SR.StreamLengthNegative);\n        }\n        \n        _safeIStream.SetSize( newLength );\n\n        // updating the stream pointer if the stream has been truncated.\n        if (newLength < this.Position)\n            this.Position = newLength;\n    }\n\n    /// <summary>\n    /// See .NET Framework SDK under System.IO.Stream\n    /// </summary>\n    /// <param name=\"buffer\">Read data buffer</param>\n    /// <param name=\"offset\">Buffer start position</param>\n    /// <param name=\"count\">Number of bytes to read</param>\n    /// <returns>Number of bytes actually read</returns>\n    public override int Read( byte[] buffer, int offset, int count )","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/CFStream.cs#L179-L215","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Validate the target length is >= 0 before calling SetLength","Clamp: stream.SetLength(Math.Max(0, newSize));","Check the value source (header/config) for corrupt or malicious data","Catch ArgumentOutOfRangeException to flag bad size computation"],"exampleFix":"// before\ncfStream.SetLength(currentSize - removedBytes);\n// after\ncfStream.SetLength(Math.Max(0, currentSize - removedBytes));","handlingStrategy":"validation","validationCode":"if (newLength < 0) throw new ArgumentOutOfRangeException(nameof(newLength), \"Length must be >= 0.\");","typeGuard":"static bool IsValidStreamLength(long len) => len >= 0 && len <= int.MaxValue;","tryCatchPattern":"try { stream.SetLength(newLength); } catch (ArgumentOutOfRangeException ex) { /* clamp and retry */ }","preventionTips":["Clamp computed sizes with Math.Max(0, x)","Validate sizes parsed from headers/config before applying them","Watch for integer overflow in size arithmetic (use checked context)"],"tags":["argument-out-of-range","stream","io","wpf"],"backgroundTag":"argument-out-of-range","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"}