Fix(Chat): keep the display bridge off windows Blizzard has not opened yet - #1913
Open
dfrisone wants to merge 1 commit into
Open
Fix(Chat): keep the display bridge off windows Blizzard has not opened yet#1913dfrisone wants to merge 1 commit into
dfrisone wants to merge 1 commit into
Conversation
Moving a chat type to a new window threw a secret-value error at ChatFrameUtil.lua:711 and left the pop-out half done. Blizzard seeds the new window from the source frame inside its own loop -- GetMessageInfo, compare the line's accessID, AddMessage -- and our AddMessage post-hook tainted the rest of that loop, so the next GetMessageInfo answered with a secret accessID. Unopened chat frames now stay unbridged, and the first integrate pass after Blizzard opens one installs the bridge and backfills our window from its buffer.
Owner
|
lmk when verified in game going to hold until then! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug: reported by Discord user 265682780711550976 in the EllesmereUI bug channel (2026-09-01, on 9.0.7). LUA error, "secrets".
Issue: right-clicking the [Guild] channel link in chat and picking Move to New Window throws "ChatFrameUtil.lua:711: attempt to compare local 'messageAccessID' (a secret number value, while execution tainted by 'EllesmereUIChat')". The new window opens and docks but stays empty, and the guild lines are still in the old tab, because the error aborts the pop-out before it copies or removes anything.
Root cause: ChatFrameUtil.PopOutChat seeds the new window from the source frame inside one loop: GetMessageInfo(i), compare that line's accessID, AddMessage, next i. The display engine bridges every chat frame with hooksecurefunc(cf, "AddMessage", EngineTail), so the first copied line enters our hook and taints the rest of Blizzard's loop. Iteration two's GetMessageInfo then answers with a secret accessID and the compare throws. The bridge's own note calls AddMessage "the LAST step of Blizzard's message pipeline", which holds for the CHAT_MSG handler it was written against but not for this copy loop.
Fix: InstallBridge now skips frames Blizzard has not opened, so the frame it hands to FCF_OpenNewWindow carries no hook while it copies. The predicate is Blizzard's own FCF_IsChatWindowIndexActive, the one FCF_GetNextOpenChatWindowIndex draws the pop-out target from, with cf.inUse for temporaries. InstallBridge reports whether it installed, and IntegrateChatFrame backfills our window from Blizzard's buffer when a frame is bridged late and our side is still empty, so the copied lines appear a tick after the pop-out. The empty check keeps a late bridge from wiping session history replayed into a window we already render. SetChatWindowShown fires UPDATE_CHAT_WINDOWS, which drives that deferred pass. Side effect: unused chat frames no longer get a bridge, a wheel handler or scroll hooks until they are opened.
Known limitation: the gate only protects a frame's first opening. hooksecurefunc cannot be undone, and restoring cf.AddMessage by hand is worse than the bug, since chat frames get their methods by Mixin copy, so the field has no metatable to fall back to and a hand-written value is read by the secure MessageEventHandler on every line. Once a frame is bridged it therefore taints any later re-seed: closing a popped-out window frees its index while the hook is still attached, and FCF_OpenTemporaryWindow sets inUse before its own identical copy loop, so a pooled whisper window reused for a second conversation is exposed the same way. Blizzard's clearable addMessageObserver slot has the same every-line read problem and is not a way out. Closing those cases means taking the tail off hooksecurefunc(cf, "AddMessage") altogether and driving the engine from chat events plus an incremental sync off cf.historyBuffer, which is what the module's own rule already points at: no EUI code may execute inside a Blizzard chat-state execution. That is an engine rewrite touching every line of live chat rendering, so it is deliberately not in this PR. This change is the containment, and it fixes the reported case.
Not yet verified in game.