[LibFFI] `nffi_prep_cif_var` Missing `safe` Method Calls
gudenau opened this issue · 2 comments
Version
3.3.3
Platform
Linux x64, Linux arm64, Linux arm32, macOS x64, macOS arm64, Windows x64, Windows x86, Windows arm64
JDK
openjdk 22-ea 2024-03-19
Module
LibFFI
Bug description
ffi_prep_cif_var
doesn't use the null safe methods to access the arguments like the related ffi_prep_cif
does. While uncommon, it is possible to call a var-arg function and pass no args to it. In order to create a FFICIF
that takes no args you pass in a null
for the PointerBuffer
argument.
Currently it is
@NativeType("ffi_status")
public static int ffi_prep_cif_var(@NativeType("ffi_cif *") FFICIF cif, @NativeType("ffi_abi") int abi, @NativeType("unsigned int") int nfixedargs, @NativeType("ffi_type *") FFIType rtype, @NativeType("ffi_type **") PointerBuffer atypes) {
return nffi_prep_cif_var(cif.address(), abi, nfixedargs, atypes.remaining(), rtype.address(), memAddress(atypes));
}
when it should probably match ffi_prep_cif
and be
@NativeType("ffi_status")
public static int ffi_prep_cif_var(@NativeType("ffi_cif *") FFICIF cif, @NativeType("ffi_abi") int abi, @NativeType("unsigned int") int nfixedargs, @NativeType("ffi_type *") FFIType rtype, @NativeType("ffi_type **") PointerBuffer atypes) {
return nffi_prep_cif_var(cif.address(), abi, nfixedargs, remainingSafe(atypes.), rtype.address(), memAddressSafe(atypes));
}
Stacktrace or crash log output
No response
Variadic functions in C require at least one fixed argument. Calling nffi_prep_cif_var
with zero arguments might happen to work on your system, but it is not guaranteed behavior across platforms.
When the official documentation of a function does not specify buffer lengths or if they are nullable or not, I examine the implementation to derive it. I may get it wrong sometimes, but I don't think this is such a case. Both ffi_prep_cif
and ffi_prep_cif_var
call an internal libffi function with this comment:
/* For non variadic functions isvariadic should be 0 and
nfixedargs==ntotalargs.
For variadic calls, isvariadic should be 1 and nfixedargs
and ntotalargs set as appropriate. nfixedargs must always be >=1 */
and these asserts:
FFI_ASSERT((!isvariadic) || (nfixedargs >= 1));
FFI_ASSERT(nfixedargs <= ntotalargs);
Woops, my bad. I was under the impression that varidic stuff could have 0 args.