mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
encoding/cbor: handle binary having more fields than the struct by discarding
This commit is contained in:
@@ -628,7 +628,8 @@ _unmarshal_map :: proc(d: Decoder, v: any, ti: ^reflect.Type_Info, hdr: Header,
|
|||||||
unknown := length == -1
|
unknown := length == -1
|
||||||
fields := reflect.struct_fields_zipped(ti.id)
|
fields := reflect.struct_fields_zipped(ti.id)
|
||||||
|
|
||||||
for idx := 0; idx < len(fields) && (unknown || idx < length); idx += 1 {
|
idx := 0
|
||||||
|
for ; idx < len(fields) && (unknown || idx < length); idx += 1 {
|
||||||
// Decode key, keys can only be strings.
|
// Decode key, keys can only be strings.
|
||||||
key: string
|
key: string
|
||||||
if keyv, kerr := decode_key(d, v, context.temp_allocator); unknown && kerr == .Break {
|
if keyv, kerr := decode_key(d, v, context.temp_allocator); unknown && kerr == .Break {
|
||||||
@@ -673,6 +674,17 @@ _unmarshal_map :: proc(d: Decoder, v: any, ti: ^reflect.Type_Info, hdr: Header,
|
|||||||
fany := any{ptr, field.type.id}
|
fany := any{ptr, field.type.id}
|
||||||
_unmarshal_value(d, fany, _decode_header(r) or_return) or_return
|
_unmarshal_value(d, fany, _decode_header(r) or_return) or_return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If there are fields left in the map that did not get decoded into the struct, decode and discard them.
|
||||||
|
if !unknown {
|
||||||
|
for _ in idx..<length {
|
||||||
|
key := err_conv(_decode_from_decoder(d, allocator=context.temp_allocator)) or_return
|
||||||
|
destroy(key, context.temp_allocator)
|
||||||
|
val := err_conv(_decode_from_decoder(d, allocator=context.temp_allocator)) or_return
|
||||||
|
destroy(val, context.temp_allocator)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
case reflect.Type_Info_Map:
|
case reflect.Type_Info_Map:
|
||||||
|
|||||||
@@ -382,6 +382,57 @@ test_lying_length_array :: proc(t: ^testing.T) {
|
|||||||
testing.expect_value(t, err, io.Error.Unexpected_EOF) // .Out_Of_Memory would be bad.
|
testing.expect_value(t, err, io.Error.Unexpected_EOF) // .Out_Of_Memory would be bad.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(test)
|
||||||
|
test_unmarshal_map_into_struct_partially :: proc(t: ^testing.T) {
|
||||||
|
|
||||||
|
// Tests that when unmarshalling into a struct that has less fields than the binary map has fields,
|
||||||
|
// the additional fields in the binary are skipped and the rest of the binary is correctly decoded.
|
||||||
|
|
||||||
|
Foo :: struct {
|
||||||
|
bar: struct {
|
||||||
|
hello: string,
|
||||||
|
world: string,
|
||||||
|
},
|
||||||
|
baz: int,
|
||||||
|
}
|
||||||
|
|
||||||
|
Foo_More :: struct {
|
||||||
|
bar: struct {
|
||||||
|
hello: string,
|
||||||
|
world: string,
|
||||||
|
hellope: string,
|
||||||
|
},
|
||||||
|
baz: int,
|
||||||
|
}
|
||||||
|
more := Foo_More{
|
||||||
|
bar = {
|
||||||
|
hello = "hello",
|
||||||
|
world = "world",
|
||||||
|
hellope = "hellope",
|
||||||
|
},
|
||||||
|
baz = 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
more_bin, err := cbor.marshal(more)
|
||||||
|
testing.expect_value(t, err, nil)
|
||||||
|
|
||||||
|
less := Foo{
|
||||||
|
bar = {
|
||||||
|
hello = "hello",
|
||||||
|
world = "world",
|
||||||
|
},
|
||||||
|
baz = 4,
|
||||||
|
}
|
||||||
|
less_out: Foo
|
||||||
|
uerr := cbor.unmarshal(string(more_bin), &less_out)
|
||||||
|
testing.expect_value(t, uerr, nil)
|
||||||
|
testing.expect_value(t, less, less_out)
|
||||||
|
|
||||||
|
delete(more_bin)
|
||||||
|
delete(less_out.bar.hello)
|
||||||
|
delete(less_out.bar.world)
|
||||||
|
}
|
||||||
|
|
||||||
@(test)
|
@(test)
|
||||||
test_decode_unsigned :: proc(t: ^testing.T) {
|
test_decode_unsigned :: proc(t: ^testing.T) {
|
||||||
expect_decoding(t, "\x00", "0", u8)
|
expect_decoding(t, "\x00", "0", u8)
|
||||||
|
|||||||
Reference in New Issue
Block a user