-
-
Notifications
You must be signed in to change notification settings - Fork 367
Creating an array buffer with V8 Sandboxing enabled corrupts the buffer data #1919
Description
When running in an V8 environment where creating external buffers is not allowed, buffer memory gets corrupted.
Take the following Rust code (lib.rs):
use napi::{Env, JsArrayBuffer};
#[napi_derive::napi]
pub fn create_buffer(env: Env) -> napi::Result<JsArrayBuffer> {
let data = vec![0xDEu8, 0xAD, 0xBE, 0xEF];
let v = env.create_arraybuffer_with_data(data)?;
Ok(v.into_raw())
}Running this in the NodeJS CLI correctly produces the correct buffer:
> const m = require("/path/to/module-from-above.node");
undefined
> m.createBuffer();
ArrayBuffer { [Uint8Contents]: <de ad be ef>, byteLength: 4 }Running this in an electron CLI produces a corrupt buffer (electron -i):
> const m = require("/path/to/module-from-above.node");
undefined
> m.createBuffer();
ArrayBuffer { [Uint8Contents]: <de 00 00 00>, byteLength: 4 }
// Content should be <de ad be ef>, only the first byte got copiedThis is happening due to a bug here:
napi-rs/crates/napi/src/env.rs
Line 464 in 80f37ee
| ptr::swap(underlying_data.cast(), data_ptr); |
More specifically, std::ptr::swap swaps 2 structures from one place to another using their structure size. In this case this means swapping *mut u8, which copies exactly one byte. The correct usage would be std::ptr::copy_nonoverlapping (the swap is not needed because u8 is Copy).
This bug seems to exist in multiple places in different variants (for example, Env::create_arraybuffer_with_borrowed_data completly fails to copy data at all when external buffers are disabled).