godotengine / godotengine/godot
Resources.Load<Json> corrupts json data by adding extra symbols to null values
- 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
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