dotnet/wpf · error · ArgumentException

bogus GorillaEncodingType passed to GetDataFromReader

Error message

bogus GorillaEncodingType passed to GetDataFromReader

What it means

GorillaCodec.GetDataFromReader decodes a single unit according to the GorillaEncodingType; an unrecognized type hits the default case and throws ArgumentException with this message. The decoder supports only the enum members it has switch cases for, so an invalid type is rejected defensively.

Solutions

  1. Validate the encoding type read from the ISF data before calling GetDataFromReader; reject or default Unknown values.
  2. Map raw int encodings through a whitelist switch to valid GorillaEncodingType members.
  3. If the payload is external, treat this as corrupt ISF: catch ArgumentException and reject or re-import the ink data.
  4. Check the producing application/version for nonstandard Gorilla encoding types.

Example fix

// before
codec.GetDataFromReader(reader, parsedEncoding, out data);
// after
if (!Enum.IsDefined(typeof(GorillaEncodingType), parsedEncoding) || parsedEncoding == GorillaEncodingType.Unknown)
    throw new InvalidDataException("Unsupported ISF encoding type");
codec.GetDataFromReader(reader, parsedEncoding, out data);
Defensive patterns

Strategy: try-catch

Validate before calling

if (!Enum.IsDefined(typeof(GorillaEncodingType), encodingType) || encodingType == GorillaEncodingType.Unknown)
    throw new InvalidDataException("ISF data uses an unsupported Gorilla encoding type");

Type guard

bool IsDecodable(GorillaEncodingType t) => Enum.IsDefined(typeof(GorillaEncodingType), t) && t != GorillaEncodingType.Unknown;

Try / catch

try { data = codec.GetDataFromReader(reader, encodingType); }
catch (ArgumentException ex) when (ex.Message.Contains("GetDataFromReader")) { /* reject payload as corrupt ISF */ }

Prevention

When it happens

Trigger: Calling GetDataFromReader with an invalid GorillaEncodingType (typically Unknown/0 or an out-of-range int cast), often an encoding value read from an ISF header that was never validated before use.

Common situations: Decoding ISF stroke data produced by a producer writing an unsupported encoding value; custom decode loops caching an enum read from bytes without mapping; uninitialized enum fields.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/InkSerializedFormat/GorillaCodec.cs:478

        private int GetDataFromReader(BitStreamReader reader, GorillaEncodingType type)
        {
            switch (type)
            {
                case GorillaEncodingType.Int:
                    {
                        return (int)reader.ReadUInt32Reverse(Native.BitsPerInt);
                    }
                case GorillaEncodingType.Short:
                    {
                        return (int)reader.ReadUInt16Reverse(Native.BitsPerShort);
                    }
                case GorillaEncodingType.Byte:
                    {
                        return (int)reader.ReadByte(Native.BitsPerByte);
                    }
                default:
                    {
                        throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("bogus GorillaEncodingType passed to GetDataFromReader"));
                    }
            }
        }


        /// <summary>
        /// Uncompress - uncompress a byte[] into an int[] of point data (x,x,x,x,x)
        /// </summary>
        /// <param name="bitCount">The number of bits each element uses in input</param>
        /// <param name="input">compressed data</param>
        /// <param name="inputIndex">index to begin decoding at</param>
        /// <param name="dtxf">data xf, can be null</param>
        /// <param name="outputBuffer">output buffer that is prealloc'd to write to</param>
        /// <param name="outputBufferIndex">the index of the output buffer to write to</param>
        internal uint Uncompress(int bitCount, byte[] input, int inputIndex, DeltaDelta dtxf, int[] outputBuffer, int outputBufferIndex)
        {
            ArgumentNullException.ThrowIfNull(input);
            ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(inputIndex, input.Length);

View on GitHub (pinned to 81131a70a4)