Thread Tools Display Modes
10-07-14, 11:09 AM   #1
Duugu
Premium Member
 
Duugu's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 851
Is this a bug in secure frames SetFrameRef/GetFrameRef?

I've found some strange behavior within the Set/GetFrameRef() thing for secure frames.

Consider the following code:

Lua Code:
  1. local header = CreateFrame("Frame", "testheader", UIParent, "SecureHandlerStateTemplate")
  2. header:SetFrameRef("ActionButton1", _G["ActionButton1"])
  3.  
  4. local button = CreateFrame("CheckButton", "testbutton1", header, "SecureActionButtonTemplate, ActionButtonTemplate")
  5. button:SetPoint("CENTER", UIParent, "CENTER")
  6.    
  7. header:WrapScript(button, "OnClick", [[
  8.     print("ActionButton1.IsForbidden =", self:GetParent():GetFrameRef("ActionButton1").IsForbidden)
  9. ]])
  10.  
  11. print("ActionButton1.IsForbidden =", _G["ActionButton1"].IsForbidden, _G["ActionButton1"]:IsForbidden())

It prints:
ActionButton1.IsForbidden = function: <.....> false
Now click the test button.

It prints:
ActionButton1.IsForbidden = nil
Ehm?

Try again:
Lua Code:
  1. print("ActionButton1.IsForbidden =", _G["ActionButton1"].IsForbidden, _G["ActionButton1"]:IsForbidden())

Result:
ActionButton1.IsForbidden = function: <.....> false
WTF??

So, is it me, or is GetFrameRef() returning something that is not equal to the original object that was passed to SetFrameRef()?
Could someone please verify if this is a bug or if I'm just stupid?

Last edited by Duugu : 10-07-14 at 11:14 AM.
  Reply With Quote
10-07-14, 03:32 PM   #2
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
Any frame in the restricted environment is restricted to restricted functions.

I don't know if you're using IsForbidden as an example or are actually trying to use it, but it wouldn't make any sense to need to call that from the restricted environment, that method basically tells you whether you can even look at a particular frame and is used pretty much exclusively for the blizzard shop.

I think you need to take a look at the wowpedia article on the restricted environment.
  Reply With Quote
10-07-14, 03:46 PM   #3
Duugu
Premium Member
 
Duugu's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 851
Hm. Well. I'm not trying to use it. I wouldn't care about it at all.

But I'm trying to use the frame handle to pass a frame reference with SetAttribute to use a type/click button.

My secure code is:
Lua Code:
  1. local tbutton = self:GetFrameRef("BABHeader"):GetFrameRef("PetActionButton1")
  2. self:SetAttribute("type2", "click")
  3. self:SetAttribute("clickbutton2", tbutton)

(assuming that PetActionButton1 was set to the frame before and is valid)

A right click throws:

6x FrameXML\SecureTemplates.lua:542: attempt to call method "IsForbidden" (a nil value)
And the code from SecureTemplates is:

Lua Code:
  1. SECURE_ACTIONS.click =
  2.     function (self, unit, button)
  3.         local delegate =
  4.             SecureButton_GetModifiedAttribute(self, "clickbutton", button);
  5.         if ( delegate and not delegate:IsForbidden() ) then
  6.             delegate:Click(button);
  7.         end
  8.     end;

(http://www.wowinterface.com/forums/s...92&postcount=5)

So, my problem is not that I can't use IsForbidden but that Blizzards secure stuff can't access IsForbidden. :/
  Reply With Quote
10-07-14, 03:59 PM   #4
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
What happens if you set the .IsForbidden to false, by yourself?
  Reply With Quote
10-07-14, 04:09 PM   #5
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
I don't have time to look into it right now, but I'm sure you can just turn your button into a macro that calls "/click PetActionButton1 RightButton" or something along those lines.
  Reply With Quote
10-07-14, 04:41 PM   #6
Duugu
Premium Member
 
Duugu's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 851
Doing
Lua Code:
  1. _G["PetActionButton1"].IsForbidden = false
unsecure sets IsForbidden to false for unsecure code.
Remains nil for secure code.

Doing it secure
Lua Code:
  1. self:GetParent():GetFrameRef("PetActionButton1").IsForbidden = false
throws
1x FrameXML\RestrictedExecution.lua:397: Call failed: <string>:" print("PetActionButton1.IsForbidden =", se...":2: attempt to index a userdata value
<in C code>
which isn't exactly what I would expect.
"attempt to index a userdata value"?? oO

Digging deeper reveals

Lua Code:
  1. function CallRestrictedClosure(signature, workingEnv, ctrlHandle, body, ...)
  2.     if (not IsWritableRestrictedTable(workingEnv)) then
  3.         error("Invalid working environment");
  4.         return;
  5.     end
  6.  
  7.     signature = tostring(signature);
  8.     local factory = LOCAL_Closure_Factories[signature];
  9.     if (not factory) then
  10.         error("Invalid signature '" .. signature .. "'");
  11.         return;
  12.     end
  13.  
  14.     local closure = factory[body];
  15.     if (not closure) then
  16.         -- Expect factory to have thrown an error
  17.         return;
  18.     end
  19.  
  20.     if (not issecure()) then
  21.         error("Cannot call restricted closure from insecure code");
  22.         return;
  23.     end
  24.  
  25.     if (type(ctrlHandle) ~= "userdata") then
  26.         ctrlHandle = nil;
  27.     end
  28.  
  29.     LOCAL_Function_Environment_Manager(true, workingEnv, ctrlHandle);
  30.     return ReleaseAndReturn(workingEnv, ctrlHandle, pcall( closure, ... ) );
  31. end

and

Lua Code:
  1. local function ReleaseAndReturn(workingEnv, ctrlHandle, pcallFlag, ...)
  2.     -- Tampering at this point will irrevocably taint the protected
  3.     -- environment, for now that's a handy protective measure.
  4.     LOCAL_Function_Environment_Manager(false, workingEnv, ctrlHandle);
  5.     if (pcallFlag) then
  6.         return ...;
  7.     end
  8.     error("Call failed: " .. tostring( (...) ) );
  9. end
  Reply With Quote
10-07-14, 04:43 PM   #7
Duugu
Premium Member
 
Duugu's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 851
Originally Posted by semlar View Post
I don't have time to look into it right now, but I'm sure you can just turn your button into a macro that calls "/click PetActionButton1 RightButton" or something along those lines.
Doh. Knowing that /click takes a button as a second argument would have been saved me 2 days full of tries, tests, and trouble. -.-

Thanks man.
  Reply With Quote
10-07-14, 10:45 PM   #8
kurapica.igas
A Chromatic Dragonspawn
Join Date: Aug 2011
Posts: 152
You can print the ActionButton1 in both restricted environment and _G, they are different objects, the "ActionButton1" in the restricted environment is an userdata, so any set/get behaviors would be checked to keep secure.

And the userdata can only access as little methods as blz wanted, you can find them in http://wowprogramming.com/utils/xmlb...ctedFrames.lua

like :

Lua Code:
  1. function HANDLE:GetName()   return GetUnprotectedHandleFrame(self):GetName() end
  2.  
  3. function HANDLE:GetID()     return GetHandleFrame(self):GetID()     end
  4. function HANDLE:IsShown()   return GetHandleFrame(self):IsShown()   end
  5. function HANDLE:IsVisible() return GetHandleFrame(self):IsVisible() end

That's the methods what the userdata can use, like GetName, GetID, IsShown, IsVisible.

The "IsForbidden" isn't defined in the file, so you will get nil from "ActionButton1.IsForbidden".
  Reply With Quote
10-08-14, 05:19 AM   #9
Duugu
Premium Member
 
Duugu's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 851
Thanks for the explanation. I know I can't access it. That's ok. The problem is that Blizzards code can't access IsForbidden.
I would consider this as a design flaw in the secure system.
  Reply With Quote

WoWInterface » Developer Discussions » General Authoring Discussion » Is this a bug in secure frames SetFrameRef/GetFrameRef?


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off