mirror of
https://github.com/extism/extism.git
synced 2026-01-09 13:57:55 -05:00
fix: Vec.as_ptr() might return a dangling pointer (#760)
Both [as_ptr][as_ptr] and [as_mut_ptr][as_mut_ptr] are allowed to return a dangling raw pointer when the Vec size is 0. The idea is that you should guard that read checking the size. This probably works well in most cases, but at the very least in the java-sdk, the JNA machinery tries to be helpful and it dereferences the pointer, causing a SIGSEGV. The solution is to check if the resulting vector is empty and return null instead. A new, empty vector would be better, but I think that would not solve the problem, because the problem is caused by a new, empty vector in the first place. Caveat: this might break consumers downstream. On the other hand: consumers that do not check for the nInput, nOutput counts are just waiting to explode, like JNA. This addresses https://github.com/extism/java-sdk/issues/27 [as_ptr]: https://doc.rust-lang.org/std/vec/struct.Vec.html#method.as_ptr [as_mut_ptr]: https://doc.rust-lang.org/std/vec/struct.Vec.html#method.as_mut_ptr Signed-off-by: Edoardo Vacchi <evacchi@users.noreply.github.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
#![allow(clippy::missing_safety_doc)]
|
||||
|
||||
use std::os::raw::c_char;
|
||||
use std::{os::raw::c_char, ptr::null_mut};
|
||||
|
||||
use crate::*;
|
||||
|
||||
@@ -231,12 +231,28 @@ pub unsafe extern "C" fn extism_function_new(
|
||||
})
|
||||
.collect();
|
||||
|
||||
// We cannot simply "get" the Vec's storage pointer because
|
||||
// the underlying storage might be invalid when the Vec is empty.
|
||||
// In that case, we return (null, 0).
|
||||
|
||||
let (inputs_ptr, inputs_len) = if inputs.is_empty() {
|
||||
(core::ptr::null(), 0 as Size)
|
||||
} else {
|
||||
(inputs.as_ptr(), inputs.len() as Size)
|
||||
};
|
||||
|
||||
let (output_ptr, output_len) = if output_tmp.is_empty() {
|
||||
(null_mut(), 0 as Size)
|
||||
} else {
|
||||
(output_tmp.as_mut_ptr(), output_tmp.len() as Size)
|
||||
};
|
||||
|
||||
func(
|
||||
plugin,
|
||||
inputs.as_ptr(),
|
||||
inputs.len() as Size,
|
||||
output_tmp.as_mut_ptr(),
|
||||
output_tmp.len() as Size,
|
||||
inputs_ptr,
|
||||
inputs_len,
|
||||
output_ptr,
|
||||
output_len,
|
||||
user_data.as_ptr(),
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user