forked from M-Labs/artiq
Fix panic when receiving empty strings in rpc calls
Receiving an empty string in an RPC call currently panics. When `length` is zero, a call to the `alloc` function (as implemented in `artiq/firmware/runtime/session.rs`) returns a null pointer. Constructing a `CMutSlice` from a null pointer panics. A `CMutSlice` consists of a pointer and the length. Rust's documentation of the `core::ptr` module states: "The canonical way to obtain a pointer that is valid for zero-sized accesses is `NonNull::dangling`." This commits adds a check for the length of a string received in an RPC call. Only for lengths greater than zero a memory allocation is performed. For zero-length strings, a dangling pointer is used. Test plan: Invoke the following experiment, which returns an empty string over RPC: ``` class ReturnEmptyString(artiq.experiment.EnvExperiment): def build(self): self.core: Core = self.get_device("core") @kernel def run(self): x = self.do_rpc() print(x) @rpc def do_rpc(self) -> TStr: return "" ``` Signed-off-by: Sven Over (Oxford Ionics) <sven.over@oxionics.com>
This commit is contained in:
parent
c73601b4b3
commit
2d017a05a1
|
@ -36,8 +36,12 @@ unsafe fn recv_value<R, E>(reader: &mut R, tag: Tag, data: &mut *mut (),
|
||||||
Tag::String | Tag::Bytes | Tag::ByteArray => {
|
Tag::String | Tag::Bytes | Tag::ByteArray => {
|
||||||
consume_value!(CMutSlice<u8>, |ptr| {
|
consume_value!(CMutSlice<u8>, |ptr| {
|
||||||
let length = reader.read_u32()? as usize;
|
let length = reader.read_u32()? as usize;
|
||||||
|
if length > 0 {
|
||||||
*ptr = CMutSlice::new(alloc(length)? as *mut u8, length);
|
*ptr = CMutSlice::new(alloc(length)? as *mut u8, length);
|
||||||
reader.read_exact((*ptr).as_mut())?;
|
reader.read_exact((*ptr).as_mut())?;
|
||||||
|
} else {
|
||||||
|
*ptr = CMutSlice::new(core::ptr::NonNull::<u8>::dangling().as_ptr(), 0);
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue