-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Size of unions is miscalculated by node-ffi-napi #15
Comments
Tracing through the code, this library appends each union member to the Line 154 in 858792b
However, node-ffi-napi will check for and then iterate over all of the elements of the #14 reworks this to only expose the biggest field via The libffi manual indicates that this isn't the best way either. Instead, it suggests (emphasis mine):
A Stack Overflow post from one of the libffi contributors suggests that |
Without this, ffi-napi will iterate through the `fields` property and **sum up** the sizes of the member fields [1]. This will cause unions to appear to be larger than they are. This can cause memory corruption on 64-bit x86 Windows when the return type should be 8 bytes (and thus be returned in a register) but ffi-napi makes it into an indirect buffer instead. Fixes node-ffi-napi#15 [1]: https://github.com/node-ffi-napi/node-ffi-napi/blob/1e7bbb170462f5f0880350cc4a518a2755b9337f/lib/type.js#L56
One (ugly!) workaround is to artificially increase the size of the union to exceed eight bytes. For example: #[repr(C)]
#[derive(Copy, Clone)]
pub struct EightBytes {
d0: u32,
d1: u32,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct ChunkyBoi {
d0: u32,
d1: u32,
d2: u32,
d3: u32,
}
#[repr(C)]
pub union TheUnion {
id: u8,
eight_bytes: EightBytes,
chunky_boi: ChunkyBoi, // Not needed, just to workaround the issue
} const EightBytes = new Struct({
d0: ref.types.uint32,
d1: ref.types.uint32,
});
const ChunkyBoi = new Struct({
d0: ref.types.uint32,
d1: ref.types.uint32,
d2: ref.types.uint32,
d3: ref.types.uint32,
});
const TheUnion = new Union({
id: ref.types.uint8,
eight_bytes: EightBytes,
chunky_boi: ChunkyBoi, // Not needed, just to workaround the issue
}); |
I created a dynamic library with a function that takes an integer and returns a union that is eight bytes. Using that function via
ref-union-di
andnode-ffi-napi
causes memory corruption on Windows x86_64.As a minimal reproduction, I have a Rust project for the library:
src/lib.rs
Cargo.toml
And basic JS usage:
index.js
package.json
Rust version 1.61.0
rustc 1.61.0 (fe5b13d68 2022-05-18)
binary: rustc
commit-hash: fe5b13d681f25ee6474be29d748c65adcd91f69e
commit-date: 2022-05-18
host: x86_64-pc-windows-msvc
release: 1.61.0
LLVM version: 14.0.0
Node version v18.3.0
Building the library and executing it yields
The text was updated successfully, but these errors were encountered: