01:53
<shu>
ljharb: you've been vocal in the past about coercing arguments in the order in which they appear. is there code that you've seen that actually depends on that ordering?
01:53
<shu>
i'm thinking of proposing a breaking change to the order of coercion for Atomics methods like Atomics.store(ta, idx, val) to coerce idx, val, then validate the TA
01:54
<shu>
with resizable buffers, having to recheck detached/out-of-boundness and reloading the length after each argument coercion is really unfortunate
01:55
<shu>
it's kind of a bugfarm (sometimes security bugs)
02:31
<ljharb>
no code i think the committee would respect, I’d guess. why is it a bug farm?
02:31
<ljharb>
I’m confused about the problem it’d be solving
02:35
<Jack Works>
Agree with shu. Don't think coerce order will break anything
02:45
<shu>
it's a bug farm because it's easy to forget that coercing idx and val can detach ta
02:45
<shu>
(and with resizable buffers, can resize ta)
02:46
<shu>
TA detachment and resizing is a qualitatively worse kind of user code than other arbitrary user code, because code that forget to recheck for detachedness after each argument coercion can end up reading out-of-bounds into the buffer, depending on the implementation
02:46
<Jack Works>
"easy to forget" do you mean when v8 is optimizing code?
02:46
<shu>
that, and i also mean engineers or spec authors actually forgetting even when implementing the slow path
02:46
<shu>
i personally missed a bunch of these in the resizable buffers spec draft
02:48
<shu>
TA and Atomics methods depend on the TA being in a valid state, life will just be a lot easier if we can rework these methods to 1) validate once instead of multiple times and 2) after validation, check that no user code can ever be called again until method exit
02:50
<shu>
I’m confused about the problem it’d be solving
what i'm solving for is "increasing likelihood of correct implementation, where incorrect implementation is often a security bug and not just misbehavior"
02:51
<shu>
to be clear, user code re-entrancy is a general problem. i'm singling out TAs because TA bugs result in more, and more serious, security bugs
02:54
<Jack Works>
So the ideal order is: idx check, val check, (no user code now), TA check, Atomics.store, (user code again)?
02:54
<shu>
it's a little trickier than that unfortunately, because val coercion depends on looking at whether ta is a BigInt TA or a non-BigInt TA
02:55
<shu>
so i think the ideal order is: coerce but not validate left-to-right, then validate left-to-right
02:55
<Jack Works>
lgtm
02:55
<shu>
so the order is: 1) ensure ta has the right internal slots, 2) coerce idx, 3) coerce val, (no user code after this point) 4) validate ta, 5) validate idx (if needed for atomic access)
03:45
<ljharb>
in general, does anything validate besides TAs and Proxy?
06:50
<Richard Gibson>
ljharb: I think that depends upon your definition of "validate". For example, there are six opportunities for String.prototype.split to throw an exception (and also observably checks arguments out-of-order)—does that count?
14:52
<ljharb>
im trying to understand she’s mental model here; it’s probably fine if TA/Proxy is “special” but i still don’t understand why it’s not easier to implement correctly if you fully process args left to right
15:02
<Ashley Claymore>
because processing later args can invalidate previous validations
15:30
<shu>
ljharb: yeah what Ashley Claymore said. fully left-to-right means you validate ta, then validate idx, then validate val, then need to validate ta again
15:31
<ljharb>
ahhhhh ok
15:32
<shu>
cause of, you know, valueOf and whatnot
15:32
<ljharb>
thanks, that makes sense now, let me think about it
15:33
<shu>
actually in the resizable case it's even dumber
15:33
<shu>
it's validate ta, validate idx, validate val, re-validate ta, then also re-validate idx because ta might not be out of bounds but just shrunk a little bit
15:34
<Ashley Claymore>
while (somethingCouldChange) validateArgs(...args)
16:32
<yulia>
rbuckton: just checking, did you see my invite for today?
16:33
<rbuckton>
I did not, no.
19:34
<ljharb>

shu: so, generally i think of "processing" arguments left to right - not necessarily validating them. meaning, i'd maybe expect something like:

  1. ensure ta is a Typed Array
  2. coerce idx to a number
  3. coerce val to whatever it needs to be, if any
  4. throw if TA is out of bounds or detached or whatever
  5. if needed, validate val

thoughts on that?

19:53
<shu>
yes that seems to match what i said above about an "ideal order"
19:53
<shu>
coerce left-to-right, then validate left-to-right
19:53
<shu>
where "coerce" is the phase that can call user code
19:53
<shu>
right now we don't have such a distinction, and we do both at the same time
19:58
<ljharb>
right. my earlier question is because i suspect most things don't actually need to "validate" (or at least, don't need to validate something that could be changed by user code post-coercion), so it doesn't come up often
20:00
<shu>
yeah
20:01
<shu>
so it sounds like you're amenable to having distinct phases like that?
20:01
<shu>
(if web compatible, of course)
20:03
<ljharb>
tentatively yes, i'd just want to make sure there's no weird cases that would arise from applying that rule universally (which might be fine ofc, but it's hard to know in advance)
20:11
<shu>
i wasn't planning on applying it universally
20:12
<shu>
though i suspect you are right that basically only TAs (and DataViews) and proxies even have a sense of "valid state" at all
20:12
<shu>
but i only really care about TAs and DataViews