Stanzilla / WoWUIBugs

World of Warcraft UI Bug Tracker
166 stars 7 forks source link

9.2.0: EmbeddedItemTooltip taint error in friendly nameplates #235

Open linaori opened 2 years ago

linaori commented 2 years ago

As of 9.2.0 there's a new item called Empty Kettle of Stone Soup. This seems to be using the EmbeddedItemTooltip, which becomes inaccessible in dungeons/raids. The taint/error can be reproduced by placing the item inside a dungeon and trying to access it through /tableinspect. It seems that even if you "style" this early, through ElvUI for example, it will cause the error later on: https://www.youtube.com/watch?v=ppf5XJGL2tE

I suspect the same would happen with Pocopoop if you were able to summon it inside a dungeon or raid.

Here's a video on the error itself https://user-images.githubusercontent.com/1754678/165629293-6c4cc46d-d091-40e2-abf1-28a82f0598e4.mp4

Addons I had active to debug (but also happens without):

The best fix would be to not make friendly nameplates forbidden/protected anymore, this would also solve a bunch of accessibility issues that addons can't solve right now, but one can always dream right? 😁

The error:

7x ...ols\Blizzard_TableInspectorAttributeDataProvider.lua:227: Attempt to access forbidden object from code tainted by an AddOn
[string "=[C]"]: in function `GetDebugName'
[string "@Blizzard_DebugTools\Blizzard_TableInspectorAttributeDataProvider.lua"]:227: in function <...ols\Blizzard_TableInspectorAttributeDataProvider.lua:221>

Locals:
(*temporary) = EmbeddedItemTooltip {
 0 = <userdata>
 BottomFontString = <unnamed> {
 }
 layoutType = "TooltipDefaultLayout"
 TextLeft1 = EmbeddedItemTooltipTextLeft1 {
 }
 ItemTooltip = <unnamed> {
 }
 BottomOverlay = <unnamed> {
 }
 textRight1Font = "GameTooltipHeaderText"
 NineSlice = <unnamed> {
 }
 textLeft2Font = "GameTooltipText"
 comparing = false
 TextRight2 = EmbeddedItemTooltipTextRight2 {
 }
 TextLeft2 = EmbeddedItemTooltipTextLeft2 {
 }
 TopOverlay = <unnamed> {
 }
 waitingForData = false
 shoppingTooltips = <table> {
 }
 needsReset = true
 updateTooltipTimer = 0.052000
 TextRight1 = EmbeddedItemTooltipTextRight1 {
 }
 textRight2Font = "GameTooltipText"
 textLeft1Font = "GameTooltipHeaderText"
}
Meorawr commented 2 years ago

I'm not sure what you're reporting here; the table inspector being insecure and unable to probe forbidden frames is intentional. Is it the fact that - when hidden - the tooltip doesn't reparent itself from the forbidden frame and back to an accessible parent such as UIParent?

If so then the solution is just that either EmbeddedItemTooltip needs a small tweak to its OnHide script to re-parent itself back to UIParent or UIWidgetTemplateTooltipMixin needs to handle re-parenting when hiding the tooltip.

linaori commented 2 years ago

I'm not sure what you're reporting here; the table inspector being insecure and unable to probe forbidden frames is intentional. Is it the fact that - when hidden - the tooltip doesn't reparent itself from the forbidden frame and back to an accessible parent such as UIParent?

The issue originally comes from ElvUI where the tooltip backdrop is being styled, and this is applied before the nameplate is even created. I'm not familiar with the inner workings of EmbeddedItemTooltip. The tooltip is modified long before it's trying to be shown from what I can tell, so I don't know if these tweaks would fix it 🤔

Basically this code is executed somewhere very early after the initial loading, where frame is _G.EmbeddedItemTooltip:

frame:SetBackdrop({
    edgeFile = [[Interface\AddOns\ElvUi\Core\Media\Textures\White8x8]],
})

For reference:

I don't know the exact process of things being loaded in ElvUI, I just know it's already loaded when the loading screen is gone based on prints in the chat if I print in these functions. There's no printing done when I hover over it, so this code is triggered only once for that tooltip.

The original error I got:

Message: Interface\SharedXML\Backdrop.lua:207: Attempt to access forbidden object from code tainted by an AddOn
Time: Tue Apr 26 00:55:35 2022
Count: 1
Stack: Interface\SharedXML\Backdrop.lua:207: Attempt to access forbidden object from code tainted by an AddOn
[string "=[C]"]: ?
[string "=[C]"]: in function `GetWidth'
[string "@Interface\SharedXML\Backdrop.lua"]:207: in function `SetupTextureCoordinates'
[string "@Interface\SharedXML\Backdrop.lua"]:176: in function <Interface\SharedXML\Backdrop.lua:174>
[string "=[C]"]: in function `SetShown'
[string "@Interface\AddOns\Blizzard_UIWidgets\Blizzard_UIWidgetTemplateBase.lua"]:102: in function `OnEnter'
[string "@Interface\AddOns\Blizzard_UIWidgets\Blizzard_UIWidgetTemplateBase.lua"]:590: in function <...Blizzard_UIWidgets\Blizzard_UIWidgetTemplateBase.lua:589>
Meorawr commented 2 years ago

I'm leaning toward this not being a Blizzard issue to fix.

The problem that I'm seeing here is that ElvUI is tainting the backdrop related fields on the EmbeddedItemTooltip when skinning it. Later, when a forbidden friendly nameplate gains a tooltip-enabled UI widget and the user hovers over it the EmbeddedItemTooltip has its owner set to a descendant of the nameplate and implicitly becomes forbidden. Upon showing, the OnSizeChanged handler for the tooltip will fire which leads to some texture setup logic for backdrops which will read the tainted backdrop fields, taint execution, and thus no longer be able to query the size of the tooltip via GetWidth() leading to the error.

As such, I think the solution here is ElvUI needs to not use the backdrop system when customizing this tooltip due to the OnSizeChanged logic requirement and forbidden nature of the tooltip. The only thing Blizzard can do otherwise is to make UI widgets use a distinct tooltip frame instead of EmbeddedItemTooltip, but that'd still effectively be unskinnable via backdrops.

linaori commented 2 years ago

I think not changing the tooltip goes against the complete nature of what ElvUI is made for, and it works fine for pretty much everything else. Perhaps removing the backdrop in an OnShow or entering an instance would "fix" it if the frame is protected? I tested something like this by first setting it as ElvUI does, and then removing it immediately after, and that prevents an error while showing a minor graphical glitch. No idea if this will still taint if it's not within the same "update" though.

This tooltip is the exception because friendly nameplates are restricted (and shouldn't be imo *hint hint blizz*), so imo it's wrong for friendly nameplates to use a frame that can easily be tainted. If this would be fixed, I'd like to see either of these two solutions, but I'll see if I can come up with something on the ElvUI side of things.

kodewdle commented 2 years ago

The only thing Blizzard can do otherwise is to make UI widgets use a distinct tooltip frame instead of EmbeddedItemTooltip, but that'd still effectively be unskinnable via backdrops.

they could make a tooltip that is specific for forbidden widgets. anyways, worked around the issue by not letting the tooltip be shown at all for this soup: https://github.com/tukui-org/ElvUI/commit/880974abe6f28677521d8bd4fec664cff22a49cd