godotengine / godotengine/godot

Resources.Load<Json> corrupts json data by adding extra symbols to null values

Open
#90,688 3 comments 0 reactions 0 assignees View on GitHub
discussion documentation topic:dotnet
Dominant language
C++
Stars
117k
Forks
26.8k
PR merge metrics
PR metrics pending

Description

### Tested versions

- Reproducible on v4.2.1.stable.mono.official [b09f793f5]

### System information

Godot v4.2.1.stable.mono - macOS 14.3.1 - Vulkan (Forward+) - integrated Apple M3 Max - Apple M3 Max (16 Threads)

Godot v4.2.1.stable.mono - Windows 10.0.19045 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3060 Laptop GPU (NVIDIA; 31.0.15.3129) - 11th Gen Intel(R) Core(TM) i7-11800H @ 2.30GHz (16 Threads)

### Issue description

`Godot.Json` Resource corrupts the original json data by adding extra symbols like <> to null values.

Deserialization of a valid json with null values, which was loaded by `Resources.Load(resPath)` results in exception:
```cs
System.Text.Json.JsonException: '<' is an invalid start of a value.
```

The below serializers are unable to deserialize the json:
- `System.Text.Json.JsonSerializer`
- `Newtonsoft.Json.JsonConvert`

Reading with `Resources.Load fails:
```cs
var json = ResourceLoader.Load(resPath);
var sample2 = JsonSerializer.Deserialize(json.Data.AsString());
```

The loaded json becomes corrupted:
```json
[
{
"Id": 10,
"Items": [
"Item 1",
"Item 2"
],
"Sounds": [
"Sound 1",
"Sound 2"
]
},
{
"Id": 11,
"Items": ,
"Sounds":
}
]
```

Reading with C# System.IO ok:
```cs
using var fs = File.OpenRead(ProjectSettings.GlobalizePath(resPath));
var sample1 = JsonSerializer.Deserialize(fs);
```
Loaded json is valid, as the original file:
```json
[
{
"Id": 10,
"Items": [
"Item 1",
"Item 2"
],
"Sounds": [
"Sound 1",
"Sound 2"
]
},
{
"Id": 11,
"Items": null,
"Sounds": null
}
]
```
Stumbled upon this while trying to embed json resources into the build. Because Json files are now treated as resources, there should be at least a property in the `Godot.Json` class to access the raw data of the original file without having those unexpected extra modifications from the Engine's side.

### Steps to reproduce

1. Obtain a valid json file with array null values inside
2. Load the json using `Resources.Load("res://data/sample.json")`
3. Deserialize the loaded json contend at `json.Data.AsString()` with `System.Text.Json.JsonSerializer.Deserialize()`
4. Observe `System.Text.Json.JsonException: '<' is an invalid start of a value.` thrown

### Minimal reproduction project (MRP)

[JsonCorrupt.zip](https://github.com/godotengine/godot/files/14975622/JsonCorrupt.zip)

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the issue with the linked JsonCorrupt.zip project and the ResourceLoader.Load call, then inspect how Godot.Json exposes json.Data.AsString(). Verify the loaded representation of null array values and compare it with the original file. Done means null values remain valid JSON and deserialize successfully with the reported serializers.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
game-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.