diff options
| author | gingerBill <bill@gingerbill.org> | 2024-03-06 11:49:17 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2024-03-06 11:49:17 +0000 |
| commit | 5eef29290c72e02620d2059ba65b52a3acf2784d (patch) | |
| tree | c1e1d35a1912fe6d9caf7641314e9b99178c69ee /core/encoding/json | |
| parent | 7ae22b7ce507dca47c3da7aa6d750a8fb557e1ad (diff) | |
Fix #3250
Diffstat (limited to 'core/encoding/json')
| -rw-r--r-- | core/encoding/json/marshal.odin | 4 | ||||
| -rw-r--r-- | core/encoding/json/parser.odin | 12 | ||||
| -rw-r--r-- | core/encoding/json/unmarshal.odin | 6 |
3 files changed, 15 insertions, 7 deletions
diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index e237892c3..6596621e8 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -365,8 +365,10 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: opt_write_start(w, opt, '{') or_return for name, i in info.names { + json_name := reflect.struct_tag_get(reflect.Struct_Tag(info.tags[i]), "json") + opt_write_iteration(w, opt, i) or_return - if json_name := string(reflect.struct_tag_get(auto_cast info.tags[i], "json")); json_name != "" { + if json_name != "" { opt_write_key(w, opt, json_name) or_return } else { opt_write_key(w, opt, name) or_return diff --git a/core/encoding/json/parser.odin b/core/encoding/json/parser.odin index 6faaf3f32..8bcef1339 100644 --- a/core/encoding/json/parser.odin +++ b/core/encoding/json/parser.odin @@ -204,8 +204,8 @@ parse_array :: proc(p: ^Parser) -> (value: Value, err: Error) { } @(private) -bytes_make :: proc(size, alignment: int, allocator: mem.Allocator) -> (bytes: []byte, err: Error) { - b, berr := mem.alloc_bytes(size, alignment, allocator) +bytes_make :: proc(size, alignment: int, allocator: mem.Allocator, loc := #caller_location) -> (bytes: []byte, err: Error) { + b, berr := mem.alloc_bytes(size, alignment, allocator, loc) if berr != nil { if berr == .Out_Of_Memory { err = .Out_Of_Memory @@ -217,9 +217,9 @@ bytes_make :: proc(size, alignment: int, allocator: mem.Allocator) -> (bytes: [] return } -clone_string :: proc(s: string, allocator: mem.Allocator) -> (str: string, err: Error) { +clone_string :: proc(s: string, allocator: mem.Allocator, loc := #caller_location) -> (str: string, err: Error) { n := len(s) - b := bytes_make(n+1, 1, allocator) or_return + b := bytes_make(n+1, 1, allocator, loc) or_return copy(b, s) if len(b) > n { b[n] = 0 @@ -290,7 +290,7 @@ parse_object :: proc(p: ^Parser) -> (value: Value, err: Error) { // IMPORTANT NOTE(bill): unquote_string assumes a mostly valid string -unquote_string :: proc(token: Token, spec: Specification, allocator := context.allocator) -> (value: string, err: Error) { +unquote_string :: proc(token: Token, spec: Specification, allocator := context.allocator, loc := #caller_location) -> (value: string, err: Error) { get_u2_rune :: proc(s: string) -> rune { if len(s) < 4 || s[0] != '\\' || s[1] != 'x' { return -1 @@ -359,7 +359,7 @@ unquote_string :: proc(token: Token, spec: Specification, allocator := context.a i += w } if i == len(s) { - return clone_string(s, allocator) + return clone_string(s, allocator, loc) } b := bytes_make(len(s) + 2*utf8.UTF_MAX, 1, allocator) or_return diff --git a/core/encoding/json/unmarshal.odin b/core/encoding/json/unmarshal.odin index 3e978fe01..e99a2729d 100644 --- a/core/encoding/json/unmarshal.odin +++ b/core/encoding/json/unmarshal.odin @@ -411,6 +411,12 @@ unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unm continue struct_loop } else { // allows skipping unused struct fields + + // NOTE(bill): prevent possible memory leak if a string is unquoted + allocator := p.allocator + defer p.allocator = allocator + p.allocator = mem.nil_allocator() + parse_value(p) or_return if parse_comma(p) { break struct_loop |