4 ms·
Okay, you definitely deserve praise for that this prevents problems in a real world scenario. Now I feel a bit bad for having made you write so much code. In t
by valenterry 6y ago
Okay, you definitely deserve praise for that this prevents problems in a real world scenario. Now I feel a bit bad for having made you write so much code.
In the evil world, I can break your code like that:
try {
add(1, 2, 3, 4)
} catch (e) {
if(e !== "You may only pass arguments a and b")
throw "boom";
}
However, you can of course make your exception string generic.
Then I'll have no choice to use one of my jokers: calling "add.toString()" and inspect your function in detail. Before you scream that this is stupid, please mind that this is actually used out there (looking for example at you, angular).
- kall 6y agoOh you wanna have a go? Let's have a go function add({ ...args }) { const { a, b, ...rest } = args; if (typeof a !== "number" || typeof b !== "number") { throw "no"; } if (Object.keys(rest).length > 0) { throw "no"; } return a + b; } function _add({ ...args }) { const { a, b, multiplier = 1, ...rest } = args; if ( typeof a !== "number" || typeof b !== "number" || typeof multiplier !== "number" ) { throw "no"; } if (Object.keys(rest).length > 0) { throw "no"; } return a + b * multiplier; } add.toString = () => "nice try"; _add.toString = () => "nice try"; Edit: OK I think we are stretching HN comment ettiquete to far with this much code. This was fun though. Thanks.
- valenterry 6y agoSure, let's do that :) if( Function.prototype.toString.call(add).includes("multiplier") ) throw "boom!"; > Edit: OK I think we are stretching HN comment ettiquete to far with this much code. This was fun though. Thanks. Huh? Would you mind to educate me about what part of the ettiquete we are not following?
- kall 6y agoIDK not a real thing, you just never see it. I feel like it's a forum not a chat room and it doesn't collapse deep threads by default so the long code makes the page very long. Probably doesn't matter though. At this point we can go ahead and break the world: add.toString = () => `function add({ ...args }) { const { a, b, ...rest } = args; if (typeof a !== "number" || typeof b !== "number") { throw "no"; } if (Object.keys(rest).length > 0) { throw "no";} return a + b;}`; _add.toString = () => `function add({ ...args }) { const { a, b, ...rest } = args; if (typeof a !== "number" || typeof b !== "number") { throw "no"; } if (Object.keys(rest).length > 0) { throw "no";} return a + b;}`; Function.prototype.toString = () => `function add({ ...args }) { const { a, b, ...rest } = args; if (typeof a !== "number" || typeof b !== "number") { throw "no"; } if (Object.keys(rest).length > 0) { throw "no";} return a + b;}`;
- valenterry 6y agoI think it's very interesting for others to follow this. Now, we are leaving the original scope (not just changing a function, but modifying globals). read-only globals even. But prepare for my counter: let frame = document.createElement('x'); document.body.appendChild(frame); if( frame.contentWindow.Function.toString.call(add).includes("multiplier") ) throw "boom!"; You might go to also kill "document.createElement", but there are many ways for me to get a new frame. I think when we come to the point where all these are disabled, I would say only a small fraction of the websites that use javascript would still properly operate. It would be your victory though. ;)
- bryik 6y ago> Before you scream that this is stupid, please mind that this is actually used out there That is stupid though. It's like saying changing a private field in Java is a breaking change because someone might have used reflection to access it. Taken to the moronic extreme: any detectable change is a breaking change because someone could write a function that pulls your latest release and depends on every bit being identical with the previous release.
- valenterry 6y agoYeah, it is stupid, but it is also true. > It's like saying changing a private field in Java is a breaking change because someone might have used reflection to access it. Which is true, both in theory and practice. Even look at misc.Unsafe - which is deliberately named unsafe and everyone was told not to use it. Then they tried to drop support for it and people freaked out so much that support was continued. (https://jaxenter.com/java-9-without-sun-misc-unsafe-119026.html https://jaxenter.com/java-9-without-sun-misc-unsafe-119026.h...) > Taken to the moronic extreme: any detectable change is a breaking change because someone could write a function that pulls your latest release and depends on every bit being identical with the previous release. I would say it is best described here: https://xkcd.com/1172/ https://xkcd.com/1172/