←back to thread

setBigTimeout

(evanhahn.com)
210 points cfj | 4 comments | | HN request time: 0s | source
Show context
n2d4 ◴[] No.41880898[source]
The default behaviour of setTimeout seems problematic. Could be used for an exploit, because code like this might not work as expected:

    const attackerControlled = ...;
    if (attackerControlled < 60_000) {
      throw new Error("Must wait at least 1min!");
    }

    setTimeout(() => {
      console.log("Surely at least 1min has passed!");
    }, attackerControlled);

The attacker could set the value to a comically large number and the callback would execute immediately. This also seems to be true for NaN. The better solution (imo) would be to throw an error, but I assume we can't due to backwards compatibility.
replies(6): >>41881042 #>>41881074 #>>41881774 #>>41882110 #>>41884470 #>>41884957 #
swatcoder ◴[] No.41881774[source]
That's just terrible input validation and has nothing to do with setTimeout.

If your code would misbehave outside a certain range of values and you're input might span a larger range, you should be checking your input against the range that's valid. Your sample code simply doesn't do that, and that's why there's a bug.

That the bug happens to involve a timer is irrelevant.

replies(3): >>41881907 #>>41885121 #>>41888700 #
1. tourist2d ◴[] No.41881907[source]
> That's just terrible input validation and has nothing to do with setTimeout.

Except for the fact that this behaviour is surprising.

> you should be checking your input against the range that's valid. Your sample code simply doesn't do that, and that's why there's a bug.

Indeed, so why doesn't setTimeout internally do that?

replies(1): >>41881963 #
2. drdaeman ◴[] No.41881963[source]
> Indeed, so why doesn't setTimeout internally do that?

Given that `setTimeout` is a part of JavaScript's ancient reptilian brain, I wouldn't be surprised it doesn't do those checks just because there's some silly compatibility requirement still lingering and no one in the committees is brave enough to make a breaking change.

(And then, what should setTimeout do if delay is NaN? Do nothing? Call immediately? Throw an exception? Personally I'd prefer it to throw, but I don't think there's any single undeniably correct answer.)

Given the trend to move away from the callbacks, I wonder why there is no `async function sleep(delay)` in the language, that would be free to sort this out nicely without having to be compatible with stuff from '90s. Or something like that.

replies(2): >>41883936 #>>41886594 #
3. ◴[] No.41883936[source]
4. erinaceousjones ◴[] No.41886594[source]
I think it's more likely that it's just "undefined behaviour" and up to the implementers of the JavaScript engines. Given that modern browsers do limit and throttle how much you can do with setTimeout in some situations (try to use setTimeout on a page after you've switched to a VR context! More than like 120hz and it'll just.... Not run the timeout anymore, from experience with Chrome).

The browser devs have decided it's acceptable to change the behaviour of setTimeout in some situations.

https://developer.chrome.com/blog/timer-throttling-in-chrome...