A security release. Every published version up to and including 0.2.1 is affected, and
upgrading is a version bump with no code changes for almost every embedder.
The problem — GHSA-6976-qm5m-7mcj
1n / ((1n << 33554399n) * 2n) ended the host process with an index out of bounds. ViperJS
exists to run untrusted JavaScript inside somebody else's program, so a script-triggered panic
is not one bug among many — it is the engine's central promise failing. Reported privately by
@Zniece, who gets the credit for finding it and for a report that
was reproducible on the first run.
What it was
One comparison against the wrong number. A left shift reserved a limb for the bits it might push
off the top, measured that width against the size ceiling, and trimmed it away again — so a
magnitude landing exactly on the ceiling was refused for room it does not keep. The refusal was
then read as impossible by the division and discarded with a default, leaving an empty divisor
to be indexed at usize::MAX.
Two silent wrong answers came from the same line and are fixed with it. On 0.2.1,
d % 7n answered 0n where the true remainder is 1n, and String(d) answered "0" —
neither of which raised anything. Those are the ones worth noticing: a panic announces itself,
and a wrong answer does not.
Also in this release
BigInt::to_digitsreturns aResult, andString(x)on a magnitude beyond the engine's
limit raises a RangeError rather than spelling"0". ECMA-262 §6.1.4 requires an
implementation that imposes a limit to throw rather than to answer something else. Breaking,
which pre-1.0 allows.- A shift landing exactly on the ceiling now succeeds, where it used to be refused.
Upgrade: viperjs = "0.2.2".