This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Exerro's profile picture

metatable variable protection

Started by Exerro, 13 March 2013 - 10:36 AM
Exerro #1
Posted 13 March 2013 - 11:36 AM
Is it possible to make it so if you try and change a variable in a table it will call a metamethod or prevent it? I've been playing around with __index and __newindex but neither of them seem to work and I can't find any more metamethods related to indexing, just math.

I want to make it so if someone tries to delete/edit a table I have, it will return false and do nothing
LBPHacker #2
Posted 13 March 2013 - 11:44 AM
Even if you have a metamethod linked to __index, I think a hacker can simply rawset() your table to nil. (I'm not sure…)
MysticT #3
Posted 13 March 2013 - 11:50 AM
There's only those (__index and __newindex), wich only work when you get (__index) a value from the table, or set new key (__newindex).
So no, you can't do it through metatables. Also, like LBPHacker said, one could simply use rawget/rawset to bypass the metatable.
Kingdaro #4
Posted 13 March 2013 - 02:18 PM
Overwrite rawset/rawget? Haha.
MysticT #5
Posted 13 March 2013 - 02:25 PM
Overwrite rawset/rawget? Haha.
Sure, that could (if done right) stop you from bypassing the metatable, but there's still no way to protect against changes to the table.
Pharap #6
Posted 13 March 2013 - 04:29 PM
A table will access its metatable's __index and __newindex when someone tries to get or set a value to/from it that does not already exist.
You can use this to stop them adding things if you treat the table you are giving the person as a reference to a hidden table ie give the reference table a metatable that will return values from the real table when indexed, but make newindex either empty or make it throw an error so they can't actually add anything to the table.
Make sure the error is on a higher level so it doesn't tell them where in your code you're causing it to error.
They can still use rawget and rawset, but they will only affect the reference table.
Don't forget to make the metatable's __metatable value reference something that isn't the actual metatable so they can't use setmetatable to remove the metatable.