Skip to content

Exception thrown when trying to deserialize a Feature, FeatureCollection, or Geometry with unrecognized properties during a partial read #143

Description

@airbreather

Fix incoming after I'm done with work for the day...

Repro

Found when deserializing objects from a chunked stream, but it's easy enough to reproduce with everything in-memory.

Program.cs

using System.Text;
using System.Text.Json;

using NetTopologySuite.Features;
using NetTopologySuite.Geometries;
using NetTopologySuite.IO.Converters;

JsonSerializerOptions options = new() { Converters = { new GeoJsonConverterFactory() } };

(Type NtsType, string Json)[] fails =
[
    (typeof(FeatureCollection[]), """
    { "type": "FeatureCollection", "_other": { } }
    """),

    (typeof(IFeature[]), """
    { "type": "Feature", "_other": { } }
    """),

    (typeof(Point[]), """
    { "type": "Point", "_other": { }, "coordinates": null }
    """),
];

for (int i = 0; i < fails.Length; i++)
{
    byte[] payload = Encoding.UTF8.GetBytes(fails[i].Json);
    using OneByOneStream s = new();
    s.WriteByte((byte)'[');
    s.Write(payload);
    for (int j = 0; j < 500; j++)
    {
        s.WriteByte((byte)',');
        s.Write(payload);
    }

    s.WriteByte((byte)']');
    s.Position = 0;
    try
    {
        _ = JsonSerializer.Deserialize(s, fails[i].NtsType, options);
        Console.Error.WriteLine("No error!");
    }
    catch (JsonException ex)
    {
        Console.Error.WriteLine($"{fails[i].Json}:");
        Console.Error.WriteLine($"{new string(' ', (int)ex.BytePositionInLine!.Value)}^");
        Console.Error.WriteLine($"    {ex.Message}");
        Console.Error.WriteLine($"    ->    {ex.InnerException?.Message}");
        Console.Error.WriteLine();
    }
}

internal sealed class OneByOneStream : MemoryStream
{
    public override int Read(Span<byte> buffer) => base.Read(buffer[..Math.Min(buffer.Length, 1)]);
    public override int Read(byte[] buffer, int offset, int count) => base.Read(buffer, offset, Math.Min(count, 1));
}

ConsoleApp0.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="NetTopologySuite.IO.GeoJSON4STJ" Version="4.0.0" />
  </ItemGroup>

</Project>

Sample output

{ "type": "FeatureCollection", "_other": { } }:
                                           ^
    The JSON value could not be converted to NetTopologySuite.Features.FeatureCollection. Path: $[0] | LineNumber: 0 | BytePositionInLine: 43.
    ->    Cannot skip tokens on partial JSON. Either get the whole payload and create a Utf8JsonReader instance where isFinalBlock is true or call TrySkip.

{ "type": "Feature", "_other": { } }:
                                 ^
    The JSON value could not be converted to NetTopologySuite.Features.IFeature. Path: $[0] | LineNumber: 0 | BytePositionInLine: 33.
    ->    Cannot skip tokens on partial JSON. Either get the whole payload and create a Utf8JsonReader instance where isFinalBlock is true or call TrySkip.

{ "type": "Point", "_other": { }, "coordinates": null }:
                               ^
    The JSON value could not be converted to NetTopologySuite.Geometries.Point. Path: $[0] | LineNumber: 0 | BytePositionInLine: 31.
    ->    Cannot skip tokens on partial JSON. Either get the whole payload and create a Utf8JsonReader instance where isFinalBlock is true or call TrySkip.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions