servo / stylo

76 stars 17 forks source link

"Safe" Gecko binding sugars allow undefined behavior in safe Rust #83

Open mbrubeck opened 7 years ago

mbrubeck commented 7 years ago

The style::gecko_bindings::sugar module implements various safe methods and traits for FFI types from Gecko. However, many of these methods are actually unsafe because they depend on invariants that are not enforced. For example, this program has undefined behavior without using unsafe:

extern crate style;
use style::gecko_bindings::structs::nsTArray;

fn main() {
    let a = nsTArray { mBuffer: std::ptr::null_mut() };
    let b = &a[..];
}

Since the structs’ fields are public, we can’t statically enforce invariants on them. Assuming we don’t want to add runtime checks, we need to make sure these methods and impls can be used only on valid struct values. Possible solutions:

SimonSapin commented 7 years ago

Generate binding structs that use pub(super) or similar to make their fields public within some trusted supermodule, but private to outside code

Another way to do this is to "flatten" that supermodule, use include!() inside of it without mod to have multiple files.