This is an automated email from the ASF dual-hosted git repository. leginee pushed a commit to branch win64-bridge-backport in repository https://gitbox.apache.org/repos/asf/openoffice.git
commit a59e4e8aabf0d4392ae6ab7078032a4b8ca5fe95 Author: Peter Kovacs <[email protected]> AuthorDate: Mon Jul 27 07:07:08 2026 +0200 bridges/msvc_win64: return queryInterface's Any in the hidden return buffer The Win64 call stack is "ret addr, this, [ret *], params", so a method with a hidden return pointer finds it at pCallStack[2] -- cpp2uno_call() reads pCppReturn from [2], and the queryInterface shortcut in cpp_mediate() reads its Type argument from [3] accordingly. That shortcut nevertheless built the returned Any at pCallStack[1] and returned [1] in the register slot. [1] is `this`, so it constructed a 24-byte Any over the proxy object and never wrote the caller's own return buffer. The caller then read and destructed an uninitialised Any, faulting in uno_any_destruct() on a stale stack value used as a typelib_TypeDescription*. The x86 bridge has always used pCallStack[2] here; the Win64 port carried over the x86 index, where the layout puts the hidden pointer before `this`. Reproducer: any queryInterface on a raw uno_Interface proxy -- e.g. pyuno's Adapter::getOutIndexes() inspecting an InvocationAdapterFactory adapter, which crashed on every use of the Python macro organiser. Co-Authored-By: Claude Opus 5 <[email protected]> --- main/bridges/source/cpp_uno/msvc_win64_x86-64/cpp2uno.cxx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/main/bridges/source/cpp_uno/msvc_win64_x86-64/cpp2uno.cxx b/main/bridges/source/cpp_uno/msvc_win64_x86-64/cpp2uno.cxx index 5deb06b112..a37c37bc21 100644 --- a/main/bridges/source/cpp_uno/msvc_win64_x86-64/cpp2uno.cxx +++ b/main/bridges/source/cpp_uno/msvc_win64_x86-64/cpp2uno.cxx @@ -301,13 +301,18 @@ extern "C" typelib_TypeClass cpp_vtable_call( if ( pInterface ) { - ::uno_any_construct( reinterpret_cast<uno_Any *>( pCallStack[1] ), + // pCallStack is "ret addr, this, [ret *], params", so the + // hidden return buffer is [2]; [1] is `this`. Writing the + // Any to [1] overwrote the proxy object and left the + // caller's return buffer untouched, so the caller then + // destructed an uninitialised Any. + ::uno_any_construct( reinterpret_cast<uno_Any *>( pCallStack[2] ), &pInterface, pTD, cpp_acquire ); pInterface->release(); TYPELIB_DANGER_RELEASE( pTD ); - reinterpret_cast<void **>( pRegisterReturn )[0] = pCallStack[1]; + reinterpret_cast<void **>( pRegisterReturn )[0] = pCallStack[2]; eRet = typelib_TypeClass_ANY; break; }
