bevyengine / bevyengine/bevy

Name component Reflect/Serde

Open
#20,767 1 comment 0 reactions 0 assignees View on GitHub
A-Reflection A-Utils C-Bug I-Regression S-Needs-Design
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 22h
Merged PRs (30d)
161

Description

## Bevy version and features

- Bevy version 0.16.1

## \[Optional\] Relevant system information

Running on `x86_64-unknown-linux-gnu`
(Debian 13 stable, rust 1.89 stable)

Using also dependencies:
- serde = 1
- bincode = 2 + features 'serde'

## What you did

Trying to serialize a component through reflection and deserialize it back.

This used to work in [bevy_sync](https://codeberg.org/raffaeleragni/bevy_sync)/[lux](https://codeberg.org/raffaeleragni/lux) in 0.15

## What went wrong

The component 'Name' apparently is having some reflection issues when serde to/from binary using reflection/registry since this version (0.16). I noticed it was refactored quite a bit since the previous 0.15 such as using Cow instead of owned String, and has a new hash field, maybe that can cause issues?

## Additional information

Sample code:
```rust
use bevy::{
prelude::*,
reflect::serde::{ReflectDeserializer, ReflectSerializer},
};
use bincode::{de::read::SliceReader, serde::OwnedSerdeDecoder};
use serde::de::DeserializeSeed;

const BINCODE_OPTIONS: bincode::config::Configuration<
bincode::config::BigEndian,
bincode::config::Fixint,
> = bincode::config::standard()
.with_big_endian()
.with_fixed_int_encoding();

fn main() {
let mut app = App::new();
app.register_type::();

let id = app.world_mut().spawn(Name::from("test")).id();
let c = app
.world()
.entity(id)
.get::()
.unwrap()
.as_partial_reflect()
.to_dynamic();

let registry = app.world().resource::();
let registry = registry.read();

println!("Encode ({c:?})");

let ser = ReflectSerializer::new(c.as_ref(), ®istry);
let binary = bincode::serde::encode_to_vec(ser, BINCODE_OPTIONS).unwrap();

println!("Decode ({binary:?})");

let deser = ReflectDeserializer::new(®istry);
let mut bin_deser = OwnedSerdeDecoder::from_reader(SliceReader::new(&binary), BINCODE_OPTIONS);
let data = deser.deserialize(bin_deser.as_deserializer()).unwrap();
let type_path = data.get_represented_type_info().unwrap().type_path();
let registration = registry.get_with_type_path(type_path).unwrap();
let rfr = registry
.get_type_data::(registration.type_id())
.unwrap();
let compo_back = rfr.from_reflect(&*data).unwrap().into_partial_reflect();

println!("{compo_back:?}");
}
```

Output:
```
Encode (DynamicStruct(bevy_ecs::name::Name { hash: 7383812325695175250, name: "test" }))
Decode ([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 20, 98, 101, 118, 121, 95, 101, 99, 115, 58, 58, 110, 97, 109, 101, 58, 58, 78, 97, 109, 101, 102, 120, 146, 48, 105, 54, 58, 82, 0, 0, 0, 0, 0, 0, 0, 4, 116, 101, 115, 116])
memory allocation of 7383812325695175250 bytes failed
Aborted (core dumped)
```

I find it *very suspicious* that it tries to allocate the same amount of the value of the hash too. This error I am getting only from this example now. While I was testing it live on bevy_sync/lux I was getting a different one but I suppose mangled bytes are mangled bytes.

I didn't find this issue with other components so far.

For comparison, when I use a Transform::default() instead of a Name component in the above example, things go smooth:

```
Encode (DynamicStruct(bevy_transform::components::transform::Transform { translation: DynamicStruct(glam::Vec3 { x: 0.0, y: 0.0, z: 0.0 }), rotation: DynamicStruct(glam::Quat { x: 0.0, y: 0.0, z: 0.0, w: 1.0 }), scale: DynamicStruct(glam::Vec3 { x: 1.0, y: 1.0, z: 1.0 }) }))
Decode ([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 48, 98, 101, 118, 121, 95, 116, 114, 97, 110, 115, 102, 111, 114, 109, 58, 58, 99, 111, 109, 112, 111, 110, 101, 110, 116, 115, 58, 58, 116, 114, 97, 110, 115, 102, 111, 114, 109, 58, 58, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 128, 0, 0, 63, 128, 0, 0, 63, 128, 0, 0, 63, 128, 0, 0])
Transform { translation: Vec3(0.0, 0.0, 0.0), rotation: Quat(0.0, 0.0, 0.0, 1.0), scale: Vec3(1.0, 1.0, 1.0) }
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.