diff options
| author | gingerBill <bill@gingerbill.org> | 2024-11-14 16:45:36 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2024-11-14 16:45:36 +0000 |
| commit | 26f67416749e45287057702af94abaae23c44e8a (patch) | |
| tree | 7b3e67247f451cc49a3edcb549f34eab482aa96a | |
| parent | 8de69091985b73b38e7f7b272ba08bc35c14dc17 (diff) | |
Check for more errors in json.unmarshal
| -rw-r--r-- | core/encoding/json/unmarshal.odin | 49 |
1 files changed, 34 insertions, 15 deletions
diff --git a/core/encoding/json/unmarshal.odin b/core/encoding/json/unmarshal.odin index 8a50989f4..ea33badae 100644 --- a/core/encoding/json/unmarshal.odin +++ b/core/encoding/json/unmarshal.odin @@ -172,20 +172,33 @@ assign_float :: proc(val: any, f: $T) -> bool { @(private) -unmarshal_string_token :: proc(p: ^Parser, val: any, str: string, ti: ^reflect.Type_Info) -> bool { +unmarshal_string_token :: proc(p: ^Parser, val: any, str: string, ti: ^reflect.Type_Info) -> (ok: bool, err: Error) { val := val switch &dst in val { case string: dst = str - return true + return true, nil case cstring: if str == "" { - dst = strings.clone_to_cstring("", p.allocator) + a_err: runtime.Allocator_Error + dst, a_err = strings.clone_to_cstring("", p.allocator) + #partial switch a_err { + case nil: + // okay + case .Out_Of_Memory: + err = .Out_Of_Memory + case: + err = .Invalid_Allocator + } + if err != nil { + return + } } else { // NOTE: This is valid because 'clone_string' appends a NUL terminator dst = cstring(raw_data(str)) } - return true + ok = true + return } #partial switch variant in ti.variant { @@ -193,31 +206,37 @@ unmarshal_string_token :: proc(p: ^Parser, val: any, str: string, ti: ^reflect.T for name, i in variant.names { if name == str { assign_int(val, variant.values[i]) - return true + return true, nil } } // TODO(bill): should this be an error or not? - return true + return true, nil case reflect.Type_Info_Integer: - i := strconv.parse_i128(str) or_return + i, pok := strconv.parse_i128(str) + if !pok { + return false, nil + } if assign_int(val, i) { - return true + return true, nil } if assign_float(val, i) { - return true + return true, nil } case reflect.Type_Info_Float: - f := strconv.parse_f64(str) or_return + f, pok := strconv.parse_f64(str) + if !pok { + return false, nil + } if assign_int(val, f) { - return true + return true, nil } if assign_float(val, f) { - return true + return true, nil } } - return false + return false, nil } @@ -304,7 +323,7 @@ unmarshal_value :: proc(p: ^Parser, v: any) -> (err: Unmarshal_Error) { case .Ident: advance_token(p) if p.spec == .MJSON { - if unmarshal_string_token(p, any{v.data, ti.id}, token.text, ti) { + if unmarshal_string_token(p, any{v.data, ti.id}, token.text, ti) or_return { return nil } } @@ -314,7 +333,7 @@ unmarshal_value :: proc(p: ^Parser, v: any) -> (err: Unmarshal_Error) { advance_token(p) str := unquote_string(token, p.spec, p.allocator) or_return dest := any{v.data, ti.id} - if !unmarshal_string_token(p, dest, str, ti) { + if !(unmarshal_string_token(p, dest, str, ti) or_return) { delete(str, p.allocator) return UNSUPPORTED_TYPE } |