1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
use crate::guest;
use crate::prelude::*;
use wasmer_runtime::Ctx;

pub fn __import_data(ctx: &mut Ctx, guest_ptr: GuestPtr) -> Result<(), WasmError> {
    if !ctx.data.is_null() {
        let b: Box<SerializedBytes> = unsafe { Box::from_raw(ctx.data as _) };
        guest::write_bytes(ctx, guest_ptr, &*b.bytes())?;
    }
    ctx.data = std::ptr::null::<SerializedBytes>() as _;
    Ok(())
}

/// always call this before setting and after using a context
/// it guards against badly behaved host/guest logic by freeing any previously leaked data pointed
/// at by the context data
#[allow(unused_assignments)]
pub fn free_context_data(data: *mut std::ffi::c_void) {
    if !data.is_null() {
        // unleak the old contents on the assumption that it is SerializedBytes
        // this assumption basically assumes that the only thing setting context data is the
        // set_context_data function below
        let _: Box<SerializedBytes> = unsafe { Box::from_raw(data as _) };
    }
}

pub fn set_context_data(ctx: &mut Ctx, serialized_bytes: SerializedBytes) -> Len {
    // guard against the situation where some bad code sets a new Ctx.data value while some other
    // data is leaked in memory, free it before setting a new value
    free_context_data(ctx.data);

    // leak the provided serialized bytes into the context data so it can be imported later
    let len = serialized_bytes.bytes().len();
    let b = Box::new(serialized_bytes);
    ctx.data = Box::into_raw(b) as _;
    len as Len
}