Skip to content

Instantly share code, notes, and snippets.

@appgurueu
Created November 27, 2023 02:13
Show Gist options
  • Save appgurueu/51ab3382fe406bd2e6c3bd087069e586 to your computer and use it in GitHub Desktop.
Save appgurueu/51ab3382fe406bd2e6c3bd087069e586 to your computer and use it in GitHub Desktop.
Randomization of `pairs` traversal order in Lua
--[[
Randomize `pairs` traversal order to deliberately break code that relies on it.
Works by doing a coin toss to decide whether to "postpone" visiting the first entry
(visiting it at the end of the traversal).
Shuffling all keys, then iterating in that shuffled order would provide more thorough randomization; however:
* It is less efficient if the loop is exited early; it may arbitrarily wreck performance
(consider a large table where `pairs` is only used to inspect very few entries.)
* I believe this simple solution already suffices for most code
that incorrectly relies on a specific order of traversal.
Notably, this has a 50% chance of breaking code that
expects `pairs` to exhibit `ipairs`-like behavior.
This does not seed the random for you,
so if you want to achieve different outcomes across different runs,
seed the random yourself.
]]
function pairs(tab)
local fk, fv = next(tab)
local sk = nil
if math.random(2) == 1 then
sk = fk
end
local f = sk ~= nil
local done = false
return function(t, k)
if done then
return nil
end
local rk, rv = next(t, k)
if rk == nil then
done = true
if f then
f = false
return fk, fv
end
return nil
end
if f and rawequal(rk, fk) then
f = false
end
return rk, rv
end, tab, sk
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment