Recent changes Random page
GAMING
Gaming
 
StarCraft Wiki
Super Smash Wiki
Halopedia
Diablo Wiki
FFXIclopedia
Grand Theft Wiki
See more...

Hooking functions safely

From WoWWiki

Jump to: navigation, search

Contents

This HOWTO discusses parameter and return value handling in a safer-than-usual way.

This HOWTO deals with pre-hooks. For details on post-hooks, see HOWTO: Post-hook a function safely.

For more information on the actual hooking of functions, see HOWTO: Hook a Function.


How you usually do it

Meet Joe Average Hook:

 local orig_foo = foo

 function foo(a1, a2)
   -- some code that looks at a1
   return orig_foo(a1, a2)
 end

The problem with this method is that it only handles a fixed number of args. If the function's API is changed in the future it could break the function completely. Fortunatly we have a way to guarantee that it'll work, both today, and in the future!

Red exclamation mark iconBlizzard's APIs do change from time to time!


The safe way to do it

local orig_foo = foo

function foo(a1, ...)
  --do something with a1 
  return orig_foo(a1, ...)
end

What this does is ensure that all args are passed to the original, even if you don't know how many args there are. We also ensure that all values are returned back. As an added bonus, the use of a local for saving the original function and making a proper tail call give us the best performance we can get, thus minimizing the cost of our hook.

Won't there be a huge performance impact?

The common pre-WoW-2.0 design, which used unpack(), created a garbage table every time the hook was called. The new design takes advantage of the new, more powerful '...' variable, removing this source of garbage. With Lua 5.1 we can ensure that all args are passed to the original, and all returns are returned out of our hook, without spending a table's worth of memory on every call.

What about tainting?

Unfortunately, there is no way to create a secure pre-hook. If tainting is an issue with your hook, you are forced to make a post-hook with hooksecurefunc().

Rate this article:
Share this article:
.