Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add serde #139

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

JonathanWoollett-Light
Copy link

Implements serde::Serialize and serde::Deserialize.

This follows up #133

@jdonszelmann
Copy link
Collaborator

Thanks for this implementation! I've actually tried once but found it a little complicated and went and did something else but we did kind of need it... neat! :)

Copy link
Collaborator

@jdonszelmann jdonszelmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

though I appreciate a lot the help, I unfortunately think this implementation isn't entirely desirable, and in at least one way I could spot sofar unsound.

S: serde::Serializer,
{
// Create a temporary Vec to store the valid elements
let mut elements = alloc::vec::Vec::with_capacity(CAP);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this alloc really necessary?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since it's basically thrown away

let mut elements = alloc::vec::Vec::with_capacity(CAP);

// Handle the case where the buffer might be empty
if self.readptr != self.writeptr {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'd be better to just use the iterator here


// Serialize the elements along with the buffer metadata
let mut state = serializer.serialize_struct("ConstGenericRingBuffer", 3)?;
state.serialize_field("elements", &elements)?;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure we need to serialize the read and writeptr tbh. Those aren't useful in a serialization and I'd be very scared deserializing them. Since soundness depends on the state of these pointers, deserializing malformed data could be unsound. Semantically, a serialized ringbufer is just a collection of elements, which when deserialized can just be pushed into a new ringbuffer, which might end up with different states for readptr/writeptr

buf[idx] = MaybeUninit::new(element);
}

Ok(ConstGenericRingBuffer {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unsound, when data is malformed. if readptr is maliciously (or accidentally) modified it'd read uninitialized elements

S: serde::Serializer,
{
// Similar to Vec's implementation, we only serialize the actual elements
// Create an iterator over the valid elements
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is an iterator over the valid elements, with self.iter()

@JonathanWoollett-Light
Copy link
Author

though I appreciate a lot the help, I unfortunately think this implementation isn't entirely desirable, and in at least one way I could spot sofar unsound.

I sort of just threw this together for something I was testing, I expect there are probably more issues than even the ones you mentioned, I don't know if I'll find the time to get this into proper shape any time soon but maybe this is a small step.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants