HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

The return bug is back.

11-07-2009, 01:27 AM#1
weaaddar
Well I perused common.j and found that indeed the return bug is back.
This new trick relies on this feller here::
Collapse Zinc:
type fogstate           extends     handle
You see fogstate is actually an integer pretending to be a handle. Meet your new native I2H::
Collapse Zinc:
native ConvertFogState(integer i)->fogstate

So what you can now do is create a handle, Get its handle Id and upconvert it to a fogstate. But what's the point?

You can use hashtables to convert it from an integer back to the type you'd like::
Collapse Zinc:
    local hashtable ht = InitHashtable();
    local unit u = CreateUnit(Player(0),'hfoo',0,0,0)
    local integer handleID = GetHandleId(u);
    local fogstate h = ConvertFogState(handleID);
    local agent a;
    call SaveFogStateHandle(ht, 0,0,h);
    set a = LoadUnitHandle(ht, 0, 0);
    call BJDebugMsg(I2S(GetHandleId(a)));

A note: hashtable's cannot be destroyed. If you want to this type of typecasting, you probably want to make a global variable for your hashtable.
Is this useless? Maybe. It might help people still using handlevars. It also might get Vex to agree that type information is USEFUL.

Blizzard taketh away, but they giveth back. The hashtable is truly awesome.
11-07-2009, 01:49 AM#2
Earth-Fury
There's also a return bug that deals with functions that return nothing somehow returning a value or the like to manipulate the stack in such a way that you can pop an arbitrary value off the stack as any type you want.

http://www.thehelper.net/forums/show....php?p=1120230

Arbitrary casting bugs are bad, and should be avoided, as it's quite possible they'll be fixed if the new I2Code is found to cause more vulnerabilities...

Edit: and for the record, GetConverted____(int) functions are all native I2H(). I do believe Player() is too, but not strait I2H() as Player(0) != null.
11-07-2009, 01:53 AM#3
TriggerHappy
It's been back.
11-07-2009, 01:55 AM#4
weaaddar
Player is not. I checked it returns different values sometimes. The point is this is pretty damn useful as now you can ignore that worthless agent type and just use handle again as converting ints<->handle and back is possible. We can now do any sort of cast (with the exception of code obviously).


The code bug is interesting, but it only works during preload if I understand as bliz blocks code reading int arrays at gametime. What would've been neat is emiting and executing dynamic code, but at last the technique only came into be after it became abolished.
Edit:
Yes, okay I get it I'm not the first, where as that will most certainly get fixed if blizzard actually cares about people running arbitrary code, I seriously doubt there going to restructure the bucketing of their HTs.
11-07-2009, 02:15 AM#5
TriggerHappy
Here is a litte framework for anyone who wants to use this;

Set NOT_HANDLE to true if the return value is not a hande (integer may be the only thing that works).

Collapse JASS:
library Typecast

    globals
        private hashtable HASH = InitHashtable()
    endglobals
    
    //! textmacro TYPECAST_MACRO takes NAME, HANDLE, RETURN, HASHFUNC, NOT_HANDLE
    function $NAME$ takes $HANDLE$ var returns $RETURN$
        static if ($NOT_HANDLE$) then
            call SaveFogStateHandle(HASH, 0,0, ConvertFogState(var))
            return $HASHFUNC$(HASH, 0, 0)
        else
            call SaveFogStateHandle(HASH, 0, 0, ConvertFogState(GetHandleId(var)))
            return $HASHFUNC$(HASH, 0, 0)
        endif
    endfunction
    //! endtextmacro
    
    //! runtextmacro TYPECAST_MACRO("I2U", "integer", "unit", "LoadUnitHandle", "true")
    
endlibrary
11-07-2009, 02:31 AM#6
Rising_Dusk
The return bug is lame and just using hashtables as intended is way more awesome. The only real use this has is that it can save maps totally overgrown of I2H abuse that hashtables alone cannot save.
11-08-2009, 01:22 AM#7
Ignitedstar
I agree with Dusk. The only reason why Blizzard tried to get rid of the return bug in the first place was because people were putting viruses and related things in maps using them. Does this mean that it can happen again using these other return bugs, though? If not, then I'm pretty sure Blizzard wouldn't care much. If so, I guess you could bring it up to them if anyone already hasn't.
11-08-2009, 03:19 AM#8
weaaddar
And this method can't save code. But it does open up a nifty replacement of SaveAgentHandle with a SaveHandleHandle
Collapse Zinc:
function SaveHandleHandle(hashtable ht,int pk,int ck,handle h)->boolean
{
    return SaveFogStateHandle(ht,pk,ck, ConvertFogState(GetHandleId(h)));
}
This might even be inlined by cjass/jasshelper.

I'm pretty sure they created agent just to avoid the mess of opening up the return bug on all types, but oh well.
11-08-2009, 03:28 AM#9
Vexorian
When they were going to make the hash table natives without anything like SaveHandleHandle, I asked why did they do that considering that SaveWidgetHandle existed, they told me only 'real handles' store type information, and thus allowing the type safety with the load natives. I then asked, why not just create a new type for the real handles and allow that type to be saved... I just wish they would have actually made triggeraction extend agent...

Can stuff stored with SaveHandleHandle actually be loaded? (Edit: apparently it can)

Blizz showed interest in fixing the "nothing" bug for some reason, so they'll likely fix this as well. I actually think handle stack corruption can lead to exploits that we don't know about and that's the reason they spent time into fixing the whole return bug instead of just disabling returns code from the syntax...

I am yet to find an old map in which replacing SetHandleHandle with a version that takes agent didn't just work. Old code just didn't mess with pseudo-handles that much, and new code does not need to rely on these things to accomplish stuff.
11-08-2009, 04:06 AM#10
Rising_Dusk
I wish no one had ever reported this fog thing, because now it might actually get fixed.
Quote:
Originally Posted by Vexorian
I am yet to find an old map in which replacing SetHandleHandle with a version that takes agent didn't just work. Old code just didn't mess with pseudo-handles that much, and new code does not need to rely on these things to accomplish stuff.
I have. I've been trying to fix it since 1.24b.
11-08-2009, 11:42 AM#11
Vexorian
In all this time it should have already been possible for you to simply replace the SetHandleHandle calls.
11-08-2009, 11:58 AM#12
weaaddar
I seriously doubt they're fixing this. The way that the hashtable is implemented is a different bucket for types, unless they remove the fogstate (which I have no idea why you'd ever need to save it), or create a "faux" handle bucket, it'll probably never be fixed.
11-08-2009, 04:38 PM#13
Rising_Dusk
Quote:
Originally Posted by Vexorian
In all this time it should have already been possible for you to simply replace the SetHandleHandle calls.
I have done that a long time ago. I have told you repeatedly that the map I refer to uses the return bug in much more ridiculous ways than just handle vars. If it were as easy as search and replace, even, I would have used Warcity.
11-08-2009, 06:28 PM#14
weaaddar
Yep, but now you can just use that new SaveHandleHandle I posted and be done with it.

I can't use any of my code as I was too trying to avoid the calls to Handle var like systems and did things like::
Collapse Zinc:
function Hero_getBag takes unit h return item
return GetStoredInteger(udg_gc,I2S(H2I(h)),"m_bag")
return null
endfunction
Although, I'm really amazed no one else tried this before me. Jesus4lyf on the helper forum seem to have figured out that all handle types are stored in the same bucket, but he was using a preloader method (where the return bug isn't caught) to use the return bug.