-
Notifications
You must be signed in to change notification settings - Fork 24
Description
I wasn't entirely sure how to use Request::header_map()
, expecting something akin to C API due to Option<&mut T>
argument, so I looked at the implementation both in cef-rs
and cef
.
Description
The way the function is currently implemented allows UB to occur from safe Rust by passing None
as argument:
fn header_map(&self, header_map: Option<&mut CefStringMultimap>) {
//...
let arg_header_map = arg_header_map
.map(|arg| arg.into_raw())
.unwrap_or(std::ptr::null_mut());
f(arg_self_, arg_header_map)
//...
}
Here, in impl ImplRequest for Request
, f
can be invoked with a null
pointer.
GetHeaderMap
is defined as:
public virtual void GetHeaderMap( HeaderMap& headerMap )= 0;
A reference is required to be initialized to refer to a valid object or function: see reference initialization.
Source: C++ Reference
In CEF implementation this reference is directly assigned to.
So bindings effectively invoke *nullptr = headermap_
when None
value is passed as argument which is UB (that results in segfault). This is impossible to achieve using the C++ API and reference is only degraded into a pointer in the C ABI exposed by bindgen.
Solution
header_map
signature should be:
fn header_map(&self, header_map: &mut CefStringMultimap) {...}
// or better yet, given that argument will be replaced (deep copied into)
fn header_map(&self) -> CefStringMultimap {...}
Related Issues
I described in detail only this one issue I stumbled across.
This is UB every time an argument which is a reference declaration in the original C++ API is defaulted as null. All of those shouldn't be wrapped in Option
in the first place because C++ API doesn't allow it. There's ~950 occurences/binding I found using regex: \.unwrap_or\(std::ptr::null(_mut)?\(\)\)
(some are false positives)