dotnet/wpf · error · ArgumentException
Invalid argument passed to ReliableRead
Error message
Invalid argument passed to ReliableRead
What it means
ReliableRead validates its inputs before reading from the stream: a null stream, null buffer, or a requestedCount larger than the buffer length causes this ArgumentException. It is an internal API-contract violation rather than a data-corruption signal — a caller passed inconsistent arguments.
Solutions
- Treat this as a symptom of corrupt ISF: check the blob's header bytes for garbage size values
- Re-serialize the ink payload rather than repairing bytes
- Ensure the Stream passed to ink deserialization is readable, non-null, and positioned at 0
- If reproducing internally, size the read buffer to at least the decoded block count
Example fix
// before var buffer = new byte[64]; ReliableRead(stream, buffer, declaredBlockSize); // throws if declaredBlockSize > 64 // after var buffer = new byte[Math.Max(declaredBlockSize, 64)]; ReliableRead(stream, buffer, declaredBlockSize);
Defensive patterns
Strategy: type-guard
Validate before calling
if (stream == null || !stream.CanRead) throw new InvalidOperationException("stream must be readable");
stream.Position = 0; Type guard
static bool IsReadable(Stream s) => s != null && s.CanRead;
Try / catch
try { strokes = LoadIsf(stream); }
catch (ArgumentException ex) { throw new InvalidDataException("ISF header declared an impossible block size (likely corrupt data)", ex); } Prevention
- Pass a readable, non-null, position-0 stream to ink deserialization
- Size read buffers to at least the decoded block count
- When this fires, suspect a corrupt ISF header upstream
- Never let user-controlled sizes index or size buffers directly
When it happens
Trigger: Internal ISF decode paths calling ReliableRead with a buffer smaller than the block size declared in the ISF header (e.g. after a size field was decoded as a huge/garbage value), or null stream/buffer.
Common situations: Mostly seen when a corrupt ISF header yields a bogus count passed through to ReliableRead; rare direct-internal misuse when custom code drives the deserialization pipeline.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- InkSerializedFormat operation failed.
- Cannot initialize compressor.
- Decompression of packet data failed.
- Drawing Attribute tag embedded in ISF stream does not match…
- Duplicate ApplicationGesture values are not allowed.
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/7afd4ee92524d707.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/InkSerializedFormat/InkSerializer.cs:1210
throw new ArgumentException(ISFDebugMessage("Invalid ISF data"),nameof(strm));
return cbSize;
}
/// <summary>
/// ReliableRead
/// </summary>
/// <param name="stream"></param>
/// <param name="buffer"></param>
/// <param name="requestedCount"></param>
/// <returns></returns>
internal static uint ReliableRead(Stream stream, byte[] buffer, uint requestedCount)
{
if (stream == null ||
buffer == null ||
requestedCount > buffer.Length)
{
throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid argument passed to ReliableRead"));
}
// let's read the whole block into our buffer
uint totalBytesRead = 0;
while (totalBytesRead < requestedCount)
{
int bytesRead = stream.Read(buffer,
(int)totalBytesRead,
(int)(requestedCount - totalBytesRead));
if (bytesRead == 0)
{
break;
}
totalBytesRead += (uint)bytesRead;
}
return totalBytesRead;
}
View on GitHub (pinned to 81131a70a4)