Found all of them (there are 34, no more)
Method:
I took the code over here and started building upon it.
Firstly, I noticed that the final function was of this form:
function(t, o, x, z, p)
{
var s,
y,
w;
var q = (Math.random() * 100) ^ 0;
var u = q < 50 ? 0 : q < 75 ? 1 : q < 88 ? 2 : 3;
s = l(o, x, z, p)[u];
y = (Math.random() * s.b) ^ 0;
var r = y;
while (y >= 0)
{
w = s.a();
if (c(231, [null, w]))
{
y = y - 1
}
}
var v = document.getElementById("error-cat");
v.src = t + w + ".jpg";
v.className = ""
};
It gets called as StackExchange.error.init('https://cdn.sstatic.net/img/error-cats/', 9, 9, 15, 1);
.
I knew that if I could remove the randomness from the code and replace it with iterations through all the possible values of the discretized random numbers, I'd be done.
Looking at var u = q < 50 ? 0 : q < 75 ? 1 : q < 88 ? 2 : 3;
, u
takes only 4 values, from 0 to 3.
Similarly, y
takes only s.b
values. s.b
is l(o, x, z, p)[u].b
. l
is defined as
l = function(r, q, o, p)
{
return [{
a: h(parseInt("thatisnot", 36)), b: r
}, {
a: h(parseInt("deadwhich", 36)), b: q
}, {
a: h(parseInt("caneternal", 36)), b: o
}, {
a: h(parseInt("lie", 36)), b: p
}]
}
The b
value is copied from the parameters of l
, which is copied from the parameters of init
. So I can just replace this code with
l = function()
{
return [{
a: h(parseInt("thatisnot", 36)), b: 9
}, {
a: h(parseInt("deadwhich", 36)), b: 9
}, {
a: h(parseInt("caneternal", 36)), b: 15
}, {
a: h(parseInt("lie", 36)), b: 1
}]
},
and then I can replace y = (Math.random() * s.b) ^ 0;
with a for loop from 0 to s.b
, where s=s = l()[u];
.
Similarly, the assignment for u
can be replaced by a for loop from 0 to 3.
One would expect this to work, but the devs are pretty sneaky and managed to create exotic errors:
TypeError: Property 'puundefinedh' of object [object Array] is not a function
This meant that for some crazy reason, someone was trying to call Array.push()
, except they were constructing the string "push"
character by character and then using a["push"]
to push to the array (if a
was the array). Such code demands immediate revocation of jQuery licenses in usual circumstances, no doubt.
Anyway, I found likely candidates for this in the code in three places:
s[k[3] + ("" + m)[0] + ("" + !!0)[3] + k[0]](x)
...
return s[k[3] + ("" + {})[1] + k[3]]()
...
t(v()[("" + !!0)[3] + ("" + m)[0] + ("" + {})[2] + ("" + !!0)[3] + ("" + {})[6] + ("" + !0)[1] + ("" + m)[5] + ("" + m)[1] + (typeof(""))[5]](v(), v()));
The first one is an obfuscation of "push"
, the second of "pop"
, the third of "substring"
. I replaced these with their literal counterparts, and the code worked.
Here is the final code. Run it in the terminal on the error page, along with StackExchange.error.init()
, and the 2D array of links should be printed to the console.
A day may come when I understand the full obfuscation, but it is not this day. This day we oscillate!
history.pushState
trickery to get a reloadable (homepage) URL into the browser's location bar?