ruabmbua / hidapi-rs

Rust bindings for the hidapi C library
MIT License
172 stars 81 forks source link

Broken string conversion in open_path #21

Closed mberndt123 closed 6 years ago

mberndt123 commented 6 years ago

Hi,

open_path starts like this:

    pub fn open_path(&self, device_path: &str) -> HidResult<HidDevice> {
        let device = unsafe { ffi::hid_open_path(std::mem::transmute(device_path.as_ptr())) };

This is not a correct way of transforming a &str to a C string. C strings need to be terminated with a NUL byte, but &str strings aren't necessarily terminated with a NUL byte because their length is stored separately. I found this out when I was trying to port a program that was working fine on my x86_64-unknown-linux-gnu machine to a mips-unkown-linux-musl machine. In that case, when I pass a string such as "0004:0004:01" to open_path, the string that ends up in the hid_open_path C function contains some trailing garbage bytes, e. g. "0004:0004:01Vrp". Needless to say, opening the device then fails.

//edit: Now that I think about it, I believe that &str is the wrong type to use for the path altogether. Afaiu, &str is supposed to be a UTF-8 string, while the path is, well, a path. On Unix-like systems that means it's an arbitrary NUL-terminated byte sequence, so it's not necessarily valid UTF-8. The type should thus be CStr. I think in the vast majority of use cases one is going to pass a path obtained from a HidDeviceInfo anyway, so it wouldn't really be any less convenient.

ruabmbua commented 6 years ago

Fixed by #12 .

Thanks for the help!