dotnet/wpf · error · ArgumentOutOfRangeException

SR.CountOfBitsOutOfRange

Error message

SR.CountOfBitsOutOfRange

What it means

BitStreamReader.ReadUInt64 only supports reading 1-64 bits per call (Native.BitsPerLong). A countOfBits outside 1..64 throws ArgumentOutOfRangeException(SR.CountOfBitsOutOfRange). Multi-quadword reads and 0-bit reads are intentionally unsupported.

Solutions

  1. Clamp countOfBits to 1..64, or split reads larger than 64 bits into multiple calls.
  2. Validate the bit width before calling; skip or reject properties with unsupported widths.
  3. Catch ArgumentOutOfRangeException around ReadUInt64 and treat the stream as corrupt.

Example fix

// before
long v = reader.ReadUInt64(bitWidth);
// after
if (bitWidth < 1 || bitWidth > 64) throw new InvalidDataException("unsupported bit width");
long v = reader.ReadUInt64(bitWidth);
Defensive patterns

Strategy: validation

Validate before calling

if (countOfBits < 1 || countOfBits > 64)
    throw new InvalidDataException($"Bit width {countOfBits} outside supported 1-64 range.");

Type guard

static bool IsValidUInt64BitCount(int bits) => bits >= 1 && bits <= 64;

Try / catch

try { long v = reader.ReadUInt64(bits); }
catch (ArgumentOutOfRangeException) { /* unsupported width: skip property or abort decode */ }

Prevention

When it happens

Trigger: Calling ReadUInt64(0), ReadUInt64(65), or with a bit count computed from external ISF data that exceeds 64.

Common situations: Decoding packet property bit widths from corrupted ISF where the declared width exceeds the supported maximum.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/Shared/MS/Internal/Ink/BitStream.cs:70

            : this(buffer)
        {
            if (bufferLengthInBits > (buffer.Length * Native.BitsPerByte))
            {
                throw new ArgumentOutOfRangeException(nameof(bufferLengthInBits), SR.InvalidBufferLength);
            }

            _bufferLengthInBits = bufferLengthInBits;
        }

        /// <summary>
        /// Read a specified number of bits from the stream into a long
        /// </summary>
        internal long ReadUInt64(int countOfBits)
        {
            // we only support 1-64 bits currently, not multiple bytes, and not 0 bits
            if (countOfBits > Native.BitsPerLong || countOfBits <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(countOfBits), countOfBits, SR.CountOfBitsOutOfRange);
            }
            long retVal = 0;
            while (countOfBits > 0)
            {
                int countToRead = (int)Native.BitsPerByte;
                if (countOfBits < 8)
                {
                    countToRead = countOfBits;
                }
                //make room
                retVal <<= countToRead;
                byte b = ReadByte(countToRead);
                retVal |= (long)b;
                countOfBits -= countToRead;
            }
            return retVal;
        }

View on GitHub (pinned to 81131a70a4)