Skip to content

Commit

Permalink
feat(c-api) Implement Drop for wasm_exporttype_t.
Browse files Browse the repository at this point in the history
`wasm_exporttype_t` has 2 fields: `name` and `extern_type`. Both are
of kind `NonNull`. When `wasm_exporttype_t` is dropped, nor `name` nor
`extern_type` are going to be dropped.

To avoid leaking data, this patch adds a new field: `owns_fields`:

* When `wasm_exporttype_t` is built from `wasm_exportype_new`, this
  field is set to `false` because `name` and `extern_type` are
  received by pointer, and its the responsibility of the caller to
  free them,

* When `wasm_exporttype_t` is built from the `From<&ExportType>`
  implementation, _we_ create `name` and `extern_type` to then leak
  them. In this case, it is safe to reconstruct proper `Box`es to
  finally drop them.
  • Loading branch information
Hywan committed Oct 8, 2020
1 parent fdb0772 commit f24a34b
Showing 1 changed file with 25 additions and 2 deletions.
27 changes: 25 additions & 2 deletions lib/c-api/src/wasm_c_api/types/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use wasmer::ExportType;
pub struct wasm_exporttype_t {
name: NonNull<wasm_name_t>,
extern_type: NonNull<wasm_externtype_t>,
owns_fields: bool,
}

wasm_declare_boxed_vec!(exporttype);
Expand All @@ -15,7 +16,11 @@ pub extern "C" fn wasm_exporttype_new(
name: NonNull<wasm_name_t>,
extern_type: NonNull<wasm_externtype_t>,
) -> Box<wasm_exporttype_t> {
Box::new(wasm_exporttype_t { name, extern_type })
Box::new(wasm_exporttype_t {
name,
extern_type,
owns_fields: false,
})
}

#[no_mangle]
Expand All @@ -33,6 +38,20 @@ pub extern "C" fn wasm_exporttype_type(
#[no_mangle]
pub extern "C" fn wasm_exporttype_delete(_exporttype: Option<Box<wasm_exporttype_t>>) {}

impl Drop for wasm_exporttype_t {
fn drop(&mut self) {
if self.owns_fields {
// SAFETY: `owns_fields` is set to `true` only in
// `wasm_exporttype_t.from(&ExportType)`, where the data
// are leaked properly and won't be freed somewhere else.
unsafe {
let _ = Box::from_raw(self.name.as_ptr());
let _ = Box::from_raw(self.extern_type.as_ptr());
}
}
}
}

impl From<ExportType> for wasm_exporttype_t {
fn from(other: ExportType) -> Self {
(&other).into()
Expand All @@ -59,6 +78,10 @@ impl From<&ExportType> for wasm_exporttype_t {
unsafe { NonNull::new_unchecked(Box::into_raw(Box::new(extern_type))) }
};

wasm_exporttype_t { name, extern_type }
wasm_exporttype_t {
name,
extern_type,
owns_fields: true,
}
}
}

0 comments on commit f24a34b

Please sign in to comment.