Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSON scalar crashes on JsonElement inputs #6023

Closed
1 task done
onionhammer opened this issue Apr 4, 2023 · 1 comment · Fixed by #6029
Closed
1 task done

JSON scalar crashes on JsonElement inputs #6023

onionhammer opened this issue Apr 4, 2023 · 1 comment · Fixed by #6029

Comments

@onionhammer
Copy link
Contributor

onionhammer commented Apr 4, 2023

Is there an existing issue for this?

  • I have searched the existing issues

Product

Hot Chocolate

Describe the bug

When an input is of type JSON, HotChocolate crashes for numeric inputs (such as 10), with the following exception

System.Text.Json.JsonReaderException: '0x00' is an invalid end of a number. Expected a delimiter. LineNumber: 0 | BytePositionInLine: 6.

Steps to reproduce

  1. Create an input with a property of type JsonElement in HC13
[QueryType]
public static class JsonBasedQuery
{
    public static string GetDataWithFilter(FilterType input)
    {
        return "hello";
    }

    public class FilterType
    {
        public string? Name { get; set; }
        public System.Text.Json.JsonElement Value { get; set; }
    }
}
  1. Invoke it with a number literal
query {
  dataWithFilter(input: {
    name: "hello"
    value: 10
  })
}

Relevant log output

  GraphQL service exception for 'POST /graphql/UnknownOperation - 4a22f1afa6b4662d460ab8929d3c10f6': '0x00' is an invalid end of a number. Expected a delimiter. LineNumber: 0 | BytePositionInLine: 2.
  System.Text.Json.JsonReaderException: '0x00' is an invalid end of a number. Expected a delimiter. LineNumber: 0 | BytePositionInLine: 2.
     at System.Text.Json.ThrowHelper.ThrowJsonReaderException(Utf8JsonReader& json, ExceptionResource resource, Byte nextByte, ReadOnlySpan`1 bytes)        
     at System.Text.Json.Utf8JsonReader.TryGetNumber(ReadOnlySpan`1 data, Int32& consumed)
     at System.Text.Json.Utf8JsonReader.ReadFirstToken(Byte first)
     at System.Text.Json.Utf8JsonReader.ReadSingleSegment()
     at System.Text.Json.Utf8JsonReader.Read()
     at System.Text.Json.JsonDocument.TryParseValue(Utf8JsonReader& reader, JsonDocument& document, Boolean shouldThrow, Boolean useArrayPools)
     at System.Text.Json.JsonElement.ParseValue(Utf8JsonReader& reader)
     at HotChocolate.Types.JsonType.JsonFormatter.Format(IValueNode node)
     at HotChocolate.Types.JsonType.ParseLiteral(IValueNode valueSyntax)
     at HotChocolate.Types.InputParser.ParseLeaf(IValueNode resultValue, ILeafType type, Path path, IInputFieldInfo field)
     at HotChocolate.Types.InputParser.ParseLiteralInternal(IValueNode value, IType type, Path path, Int32 stack, Boolean defaults, IInputFieldInfo field)  
     at HotChocolate.Types.InputParser.ParseLiteralInternal(IValueNode value, IType type, Path path, Int32 stack, Boolean defaults, IInputFieldInfo field)  
     at HotChocolate.Types.InputParser.ParseObject(IValueNode resultValue, InputObjectType type, Path path, Int32 stack, Boolean defaults)
     at HotChocolate.Types.InputParser.ParseLiteralInternal(IValueNode value, IType type, Path path, Int32 stack, Boolean defaults, IInputFieldInfo field)  
     at HotChocolate.Types.InputParser.ParseLiteralInternal(IValueNode value, IType type, Path path, Int32 stack, Boolean defaults, IInputFieldInfo field)  
     at HotChocolate.Types.InputParser.ParseLiteral(IValueNode value, IInputFieldInfo field, Type targetType)
     at HotChocolate.Execution.Processing.MiddlewareContext.CoerceArgumentValue[T](ArgumentValue argument)
     at HotChocolate.Execution.Processing.MiddlewareContext.ArgumentValue[T](String name)
     at DataAnnotatedModelValidations.ValidatorMiddleware.<>c__DisplayClass6_0.<ReportErrorFactory>b__0(IInputField argument)
     at System.Linq.Parallel.ForAllOperator`1.ForAllEnumerator`1.MoveNext(TInput& currentElement, Int32& currentKey)
     at System.Linq.Parallel.ForAllSpoolingTask`2.SpoolingWork()
     at System.Linq.Parallel.SpoolingTaskBase.Work()
     at System.Linq.Parallel.QueryTask.BaseWork(Object unused)
     at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
  --- End of stack trace from previous location ---
     at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
     at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)

Additional Context?

No response

Version

13.0.5

@onionhammer onionhammer changed the title JSON scalar does not support number literal inputs JSON scalar crashes with number literal inputs Apr 4, 2023
@onionhammer
Copy link
Contributor Author

onionhammer commented Apr 5, 2023

Seems like this code
image

The JSON reader continues to read the underlying input buffer, even though only 2 bytes were written the underlying buffer is 512 bytes
image

The solution is to pass in the bytes actually written to the call to GetSpan so it only returns the relevant bytes rather than its initial buffer size.

@onionhammer onionhammer changed the title JSON scalar crashes with number literal inputs JSON scalar crashes on JsonElement inputs Apr 5, 2023
onionhammer added a commit to onionhammer/graphql-platform that referenced this issue Apr 5, 2023
@michaelstaib michaelstaib added this to the HC-13.1.0 milestone Apr 6, 2023
michaelstaib added a commit that referenced this issue Apr 12, 2023
Co-authored-by: Michael Staib <michael@chillicream.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants