Merge pull request #2838 from GoNZooo/gonz.return-out-of-memory-in-json-parse

fix(json): return `.Out_Of_Memory` when out of memory on parse
This commit is contained in:
gingerBill
2023-10-15 11:23:34 +01:00
committed by GitHub
2 changed files with 55 additions and 2 deletions

View File

@@ -263,8 +263,17 @@ parse_object_body :: proc(p: ^Parser, end_token: Token_Kind) -> (obj: Object, er
return
}
obj[key] = elem
// NOTE(gonz): There are code paths for which this traversal ends up
// inserting empty key/values into the object and for those we do not
// want to allocate anything
if key != "" {
reserve_error := reserve(&obj, len(obj) + 1)
if reserve_error == mem.Allocator_Error.Out_Of_Memory {
return nil, .Out_Of_Memory
}
obj[key] = elem
}
if parse_comma(p) {
break
}

View File

@@ -4,6 +4,7 @@ import "core:encoding/json"
import "core:testing"
import "core:fmt"
import "core:os"
import "core:mem/virtual"
TEST_count := 0
TEST_fail := 0
@@ -77,6 +78,49 @@ parse_json :: proc(t: ^testing.T) {
expect(t, err == nil, msg)
}
@test
out_of_memory_in_parse_json :: proc(t: ^testing.T) {
arena: virtual.Arena
arena_buffer: [256]byte
arena_init_error := virtual.arena_init_buffer(&arena, arena_buffer[:])
testing.expect(t, arena_init_error == nil, fmt.tprintf("Expected arena initialization to not return error, got: %v\n", arena_init_error))
context.allocator = virtual.arena_allocator(&arena)
json_data := `
{
"firstName": "John",
"lastName": "Smith",
"isAlive": true,
"age": 27,
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021-3100"
},
"phoneNumbers": [
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "office",
"number": "646 555-4567"
}
],
"children": [],
"spouse": null
}
`
_, err := json.parse(transmute([]u8)json_data)
expected_error := json.Error.Out_Of_Memory
msg := fmt.tprintf("Expected `json.parse` to fail with %v, got %v", expected_error, err)
expect(t, err == json.Error.Out_Of_Memory, msg)
}
@test
marshal_json :: proc(t: ^testing.T) {