{"record":{"id":"3618ba68db6dec6f","repo":"dotnet/wpf","slug":"sr-seeknegative-versionedstreamowner","errorCode":null,"errorMessage":"SR.SeekNegative","messagePattern":"SR\\.SeekNegative","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/VersionedStreamOwner.cs","lineNumber":85,"sourceCode":"            long temp = -1;\n            switch (origin)\n            {\n                // seek beyond the FormatVersion\n                case SeekOrigin.Begin:\n                    temp = offset;\n                    break;\n\n                case SeekOrigin.Current:\n                    checked { temp = Position + offset; }\n                    break;\n\n                case SeekOrigin.End:\n                    checked { temp = Length + offset; }\n                    break;\n            }\n\n            if (temp < 0)\n                throw new ArgumentException(SR.SeekNegative);\n\n            checked { BaseStream.Position = temp + _dataOffset; }\n            return temp;\n        }\n\n        /// <summary>\n        /// SetLength\n        /// </summary>\n        public override void SetLength(long newLength)\n        {\n            ArgumentOutOfRangeException.ThrowIfNegative(newLength);\n\n            WriteAttempt();\n            checked { BaseStream.SetLength(newLength + _dataOffset); }\n        }\n\n        /// <summary>\n        /// Flush","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/VersionedStreamOwner.cs#L67-L103","documentation":"ArgumentException (SR.SeekNegative) thrown by VersionedStreamOwner.Seek when the computed new position (depending on SeekOrigin.Begin/Current/End plus the offset) is negative — i.e. seeking before the start of the stream data. .NET streams do not allow negative positions, so the call is rejected.","triggerScenarios":"Calling Seek with a negative offset from SeekOrigin.Begin, or an offset from Current/End large enough that Length+offset < 0 (e.g. Seek(-1000, SeekOrigin.End) on a 100-byte stream). Reached both directly and via the Position setter.","commonSituations":"Off-by-sign errors when computing relative offsets; saving/restoring a position captured from a different stream; integer underflow when mixing Int32 offsets with long lengths; seeking relative to End on streams assumed larger than they are.","solutions":["Clamp or validate the computed target position to >= 0 before calling Seek","Capture positions with a positive-origin Seek (SeekOrigin.Begin) rather than relative arithmetic","Restore saved positions only on the same stream they were captured from","Use checked arithmetic for offset computations to surface underflow at the right place"],"exampleFix":"// before: unguarded relative seek from End\nlong target = fileLength + delta; // delta may underflow\nstream.Seek(target, SeekOrigin.Begin);\n// after: clamp to the valid range\nlong target = Math.Max(0, fileLength + delta);\nstream.Seek(target, SeekOrigin.Begin);","handlingStrategy":"validation","validationCode":"static long ClampSeek(long origin, long offset, long length) => Math.Max(0, origin switch\n{\n    SeekOrigin.Begin => offset,\n    SeekOrigin.Current => offset,\n    SeekOrigin.End => length + offset,\n    _ => throw new ArgumentOutOfRangeException(nameof(origin))\n});","typeGuard":null,"tryCatchPattern":"try\n{\n    stream.Seek(target, SeekOrigin.Begin);\n}\ncatch (ArgumentException ex) when (ex.Message.Contains(\"negative\"))\n{\n    logger.LogWarning(ex, \"Seek before start of stream; clamping to 0.\");\n    stream.Seek(0, SeekOrigin.Begin);\n}","preventionTips":["Always compute seek targets with checked, positive-anchored arithmetic","Clamp computed positions to [0, Length] before seeking","Never restore saved positions onto a different stream instance","Unit-test seek math with offsets larger than stream length"],"tags":["seek","argument-out-of-range","stream","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-22T01:17:13.364Z"}