tokio-rs / valuable

MIT License
185 stars 19 forks source link

`NamedValues::get` footgun. #101

Open jswrenn opened 2 years ago

jswrenn commented 2 years ago

NamedValues::get has a subtle footgun: The given reference to a NamedField must be pointer-equal to a NamedField in NamedValues. But, because NamedField is Copy/Clone, it's trivial to construct programs that subtly violate this requirement; e.g., this program panics:

fn main() {
    use valuable::{NamedField, NamedValues, Value};

    let fields = [
        NamedField::new("foo"),
        NamedField::new("bar")
    ];
    let values = [
        Value::U32(123),
        Value::U32(456),
    ];

    let named_values = NamedValues::new(&fields, &values);

    let field = fields[0];

    assert_eq!(
        named_values.get(&field).and_then(Value::as_u32),
        Some(123)
    );
}

...but this program is fine:

fn main() {
    use valuable::{NamedField, NamedValues, Value};

    let fields = [
        NamedField::new("foo"),
        NamedField::new("bar")
    ];
    let values = [
        Value::U32(123),
        Value::U32(456),
    ];

    let named_values = NamedValues::new(&fields, &values);

    let field = &fields[0];

    assert_eq!(
        named_values.get(field).and_then(Value::as_u32),
        Some(123)
    );
}