You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
number + typedArray[<out-of-bounds index>] evaluates to undefined instead of the spec-mandated NaN. The out-of-bounds typed-array element read correctly yields undefined, but the subsequent numeric + fails to ToNumber it (which should give NaN), and the TAG_UNDEFINED sentinel leaks through to the result.
Repro
functionreadAdd(S: Int32Array,i: number): number{return1000+S[i];}consta=Int32Array.from([10,20,30,40]);console.log(readAdd(a,99));// Node: NaN Perry: undefinedconsole.log(readAdd(a,-1));// Node: NaN Perry: undefinedconsole.log(1000+a[99]);// Node: NaN Perry: undefined
node --experimental-strip-types prints NaN for all three; Perry prints undefined.
Scope / notes
Pre-existing and independent of any fast path: reproduces regardless of PERRY_TA_PARAM_F64_READ (on and off are bit-exact), i.e. it's present for the plain js_typed_array_get read path on main.
Likely in the + lowering / js_dynamic_string_or_number_add handling of an undefined (TAG_UNDEFINED) operand: it should apply ToNumber(undefined) = NaN, not propagate the undefined sentinel. Other numeric ops (-, *) may share the bug (1000 - a[99], 2 * a[99]).
String(a[99]) → "undefined", a[99] === undefined → true, and a[99] | 0 → 0 are all correct; only the ToNumber-via-arithmetic path is wrong.
Summary
number + typedArray[<out-of-bounds index>]evaluates toundefinedinstead of the spec-mandatedNaN. The out-of-bounds typed-array element read correctly yieldsundefined, but the subsequent numeric+fails toToNumberit (which should giveNaN), and theTAG_UNDEFINEDsentinel leaks through to the result.Repro
node --experimental-strip-typesprintsNaNfor all three; Perry printsundefined.Scope / notes
PERRY_TA_PARAM_F64_READ(on and off are bit-exact), i.e. it's present for the plainjs_typed_array_getread path onmain.+lowering /js_dynamic_string_or_number_addhandling of anundefined(TAG_UNDEFINED) operand: it should applyToNumber(undefined) = NaN, not propagate the undefined sentinel. Other numeric ops (-,*) may share the bug (1000 - a[99],2 * a[99]).String(a[99])→"undefined",a[99] === undefined→true, anda[99] | 0→0are all correct; only theToNumber-via-arithmetic path is wrong.=== undefined/String()contexts to avoid this unrelated bug). Does not affect bcrypt (_encipherindices are all masked in-bounds).