This is an automated email from the ASF dual-hosted git repository. leginee pushed a commit to branch win10-msvc-trunk in repository https://gitbox.apache.org/repos/asf/openoffice.git
commit a1d258c26ad155e41be44bf3267158aabd4a7c9e Author: Peter Kovacs <[email protected]> AuthorDate: Sat Aug 29 13:54:12 2026 +0200 svtools: the autoswap sentinels have to survive Link::Call's long return GRFMGR_AUTOSWAPSTREAM_* are not streams. They are sentinels a swap handler returns in place of one, and they come back through Link::Call(), whose return type is long -- 32 bit on Windows x64. GraphicObject::GetSwapStream() casts that long straight back to SvStream* (grfmgr.cxx:487), so the value every comparison sees is the sentinel truncated to 32 bits and widened again. Written as (SvStream*)0xffffffffUL, _NONE is 0x00000000ffffffff, but comes back from that round trip as 0xffffffffffffffff and equals none of the four. ImplAutoSwapOutHdl() then takes it for a real stream and writes the graphic to address 0xffffffffffffffff -- the access violation on deleting a Gallery graphic. Spelling them as negative sal_IntPtr settles it in both directions: where long is pointer-sized the bit patterns are exactly what they were, and where it is not, the truncated value sign-extends back to precisely these constants, so the comparisons match again. On LP64 the numeric values do change -- _NONE becomes 0xffffffffffffffff rather than 0x00000000ffffffff. That is harmless because the sentinels are only ever compared against each other and never persisted, but it does mean all three modules that name them -- svtools, svx and sw -- have to be built together, not svtools alone. The narrowing return type is the real defect and is deliberately not touched here: Link is a public interface used across the whole product. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01UWgzQY2r1XwFvgeLPFWPsi --- main/svtools/inc/svtools/grfmgr.hxx | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/main/svtools/inc/svtools/grfmgr.hxx b/main/svtools/inc/svtools/grfmgr.hxx index 9a19c20a08..b91caecb57 100644 --- a/main/svtools/inc/svtools/grfmgr.hxx +++ b/main/svtools/inc/svtools/grfmgr.hxx @@ -43,10 +43,20 @@ // - AutoSwap Defines - // -------------------- -#define GRFMGR_AUTOSWAPSTREAM_LINK ((SvStream*)0x00000000UL) -#define GRFMGR_AUTOSWAPSTREAM_LOADED ((SvStream*)0xfffffffdUL) -#define GRFMGR_AUTOSWAPSTREAM_TEMP ((SvStream*)0xfffffffeUL) -#define GRFMGR_AUTOSWAPSTREAM_NONE ((SvStream*)0xffffffffUL) +/* These four are not streams: they are sentinels that a swap handler returns + in place of one. The handler hands them back through Link::Call(), whose + return type is long -- 32 bit on Windows x64 -- so a 64-bit pointer value + makes the round trip only if it survives truncation to long and the cast + back. Spelling the sentinels as negative sal_IntPtr does that: the bits + are unchanged where long is pointer-sized, and where it is not, the cast + back sign-extends to exactly these values, so the comparisons in + GraphicObject::ImplAutoSwapOutHdl()/ImplAutoSwapIn() still match. Written + as 0xffffffffUL they did not, and _NONE arrived there as a stream to write + to. */ +#define GRFMGR_AUTOSWAPSTREAM_LINK ((SvStream*)(sal_IntPtr) 0) +#define GRFMGR_AUTOSWAPSTREAM_LOADED ((SvStream*)(sal_IntPtr)-3) +#define GRFMGR_AUTOSWAPSTREAM_TEMP ((SvStream*)(sal_IntPtr)-2) +#define GRFMGR_AUTOSWAPSTREAM_NONE ((SvStream*)(sal_IntPtr)-1) // ---------------------- // - Adjustment Defines -
