tls: fix convertALPNProtocols accepting ArrayBufferViews#43211
tls: fix convertALPNProtocols accepting ArrayBufferViews#43211LiviaMedeiros merged 1 commit intonodejs:masterfrom
Conversation
|
Review requested:
|
This comment was marked as outdated.
This comment was marked as outdated.
403e1e3 to
15930c1
Compare
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
| if (ArrayIsArray(protocols)) { | ||
| out.ALPNProtocols = convertProtocols(protocols); | ||
| } else if (isArrayBufferView(protocols)) { | ||
| } else if (Buffer.isBuffer(protocols) || isUint8Array(protocols)) { |
There was a problem hiding this comment.
Is isUint8Array() faster than isArrayBufferView()? If not we can remove it as it would be handled by the isArrayBufferView() check below.
There was a problem hiding this comment.
The question here is, is Buffer.from(buffer) faster or better than Buffer.from(arrayBuffer, byteOffset, length)? Having Buffer or Uint8Array here is expected in most cases, otherwise we would got bugreports for this.
I don't really know but my guess is "yes, it should be faster" because Buffer tends to use shared pools, and by doing buffer.slice() we would copy the whole pool.
There was a problem hiding this comment.
I don't really know but my guess is "yes, it should be faster" because
Buffertends to use shared pools, and by doingbuffer.slice()we would copy the whole pool.
We should keep it as is when protocols is a Buffer but when it is an Uint8Array I'm not sure. AFAIK there is no pool for Uint8Arrays.
There was a problem hiding this comment.
Anyway it is not very important, it would only slightly improve readability by removing the OR condition. Feel free to ignore.
There was a problem hiding this comment.
Hmm, tested it and
const { Buffer } = require('node:buffer');
console.log(Buffer.from(new Uint8Array([1,2,3])).buffer.byteLength);Shows 8192 😕
There was a problem hiding this comment.
$ node
Welcome to Node.js v18.2.0.
Type ".help" for more information.
> const arr = new Uint8Array([1,2,3]);
undefined
> arr.buffer.byteLength
3
> const buf = Buffer.from(arr.slice(), arr.byteOffset, arr.byteLength);
undefined
> buf.buffer.byteLength
8192
There was a problem hiding this comment.
$ ./node
Welcome to Node.js v19.0.0-pre.
Type ".help" for more information.
> const arr = new Uint8Array([1,2,3]);
undefined
> const buf = Buffer.from(arr.buffer.slice(), arr.byteOffset, arr.byteLength);
undefined
> buf.buffer.byteLength
3The one above uses Uint8Array directly rather than ArrayBuffer :)
There was a problem hiding this comment.
Isn't that the point of speedup? I mean, because of that in practice we should prefer doing Buffer.from(arr) directly so it will be able to reuse preallocated pool.
Yes, it makes sense.
There was a problem hiding this comment.
Actually, it was the right direction, applicable to the next branch. I forgot that TypedArray.prototype.slice().buffer, unlike Buffer's version, does exactly what's needed there. Calling .buffer.slice() without arguments is in fact a huge mistake.
Unfortunately, DataView is not a TypedArray and supporting it requires slightly different approach.
Synthetic microbenchmarking shows ~50% speedup for TypedArray way over DataView, and ~700% for Buffer|Uint8Array way over DataView for me.
If readability suffered too much from that, last else if (isArrayBufferView) branch can be removed. Otherwise it seems to be the most correct workaround (at least until Buffer.from(anyArrayBufferView) is somehow supported 😄).
This comment was marked as outdated.
This comment was marked as outdated.
PR-URL: nodejs#43211 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
220bc10 to
15a682c
Compare
|
Landed in 15a682c |
|
The tls/convertprotocols.js benchmark is showing a ~7.5% performance regression after this commit. Looking at the changes, do we really need |
|
The node/benchmark/tls/convertprotocols.js Line 11 in d72dcb0 Which is covered by the very first condition; so I'm not sure as well. As long as it doesn't affect readability, yes, it's worth a try to remove |
PR-URL: #43211 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
PR-URL: nodejs#43211 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
PR-URL: #43211 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
PR-URL: #43211 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
PR-URL: #43211 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
PR-URL: nodejs/node#43211 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Fix for
ArrayBufferViews that are notUint8Array.I believe it should be eventually adjusted on
bufferside, but not sure if it would be easy or worth potential breakage.Audit through
make testgave me two misuses, both test-only and safe:node/test/parallel/test-buffer-alloc.js
Lines 46 to 47 in a346572
node/test/parallel/test-webcrypto-random.js
Lines 50 to 51 in a346572
However, there could still be similar bugs within
cryptoin places whereBuffer.from(buffer)is used./cc @nodejs/crypto