|
9 | 9 | DataViewPrototypeGetBuffer, |
10 | 10 | DataViewPrototypeGetByteLength, |
11 | 11 | DataViewPrototypeGetByteOffset, |
| 12 | + MathFloor, |
12 | 13 | Number, |
13 | 14 | ObjectDefineProperty, |
14 | 15 | ObjectEntries, |
@@ -550,6 +551,46 @@ function validateMaxBufferLength(data, name, max = kMaxBufferLength) { |
550 | 551 | } |
551 | 552 | } |
552 | 553 |
|
| 554 | +/** |
| 555 | + * Converts a bit length to the number of bytes needed to contain it. |
| 556 | + * Non-byte lengths are rounded up to the next byte. |
| 557 | + * @param {number} length |
| 558 | + * @returns {number} |
| 559 | + */ |
| 560 | +function numBitsToBytes(length) { |
| 561 | + return MathFloor(length / 8) + MathFloor((7 + (length % 8)) / 8); |
| 562 | +} |
| 563 | + |
| 564 | +/** |
| 565 | + * Copies `bytes` up to the byte length needed for `length` bits, then clears |
| 566 | + * unused least-significant bits in the final byte. |
| 567 | + * @param {number} length |
| 568 | + * @param {ArrayBuffer|ArrayBufferView} bytes |
| 569 | + * @returns {Uint8Array} |
| 570 | + */ |
| 571 | +function truncateToBitLength(length, bytes) { |
| 572 | + const lengthBytes = numBitsToBytes(length); |
| 573 | + const isView = ArrayBufferIsView(bytes); |
| 574 | + const byteView = isView ? |
| 575 | + new Uint8Array( |
| 576 | + getDataViewOrTypedArrayBuffer(bytes), |
| 577 | + getDataViewOrTypedArrayByteOffset(bytes), |
| 578 | + getDataViewOrTypedArrayByteLength(bytes), |
| 579 | + ) : |
| 580 | + new Uint8Array(bytes, 0, ArrayBufferPrototypeGetByteLength(bytes)); |
| 581 | + const result = TypedArrayPrototypeSlice( |
| 582 | + byteView, |
| 583 | + 0, |
| 584 | + lengthBytes, |
| 585 | + ); |
| 586 | + |
| 587 | + const remainder = length % 8; |
| 588 | + if (remainder !== 0) |
| 589 | + result[lengthBytes - 1] &= (0xff << (8 - remainder)) & 0xff; |
| 590 | + |
| 591 | + return result; |
| 592 | +} |
| 593 | + |
553 | 594 | let webidl; |
554 | 595 |
|
555 | 596 | // Keep this as a regular object. The WebIDL converters read and spread these |
@@ -609,12 +650,19 @@ function normalizeAlgorithm(algorithm, op) { |
609 | 650 | // 3. |
610 | 651 | if (idlType === 'BufferSource' && idlValue) { |
611 | 652 | const isView = ArrayBufferIsView(idlValue); |
612 | | - normalizedAlgorithm[member] = TypedArrayPrototypeSlice( |
| 653 | + const idlValueBytes = isView ? |
613 | 654 | new Uint8Array( |
614 | | - isView ? getDataViewOrTypedArrayBuffer(idlValue) : idlValue, |
615 | | - isView ? getDataViewOrTypedArrayByteOffset(idlValue) : 0, |
616 | | - isView ? getDataViewOrTypedArrayByteLength(idlValue) : ArrayBufferPrototypeGetByteLength(idlValue), |
617 | | - ), |
| 655 | + getDataViewOrTypedArrayBuffer(idlValue), |
| 656 | + getDataViewOrTypedArrayByteOffset(idlValue), |
| 657 | + getDataViewOrTypedArrayByteLength(idlValue), |
| 658 | + ) : |
| 659 | + new Uint8Array( |
| 660 | + idlValue, |
| 661 | + 0, |
| 662 | + ArrayBufferPrototypeGetByteLength(idlValue), |
| 663 | + ); |
| 664 | + normalizedAlgorithm[member] = TypedArrayPrototypeSlice( |
| 665 | + idlValueBytes, |
618 | 666 | ); |
619 | 667 | } else if (idlType === 'HashAlgorithmIdentifier') { |
620 | 668 | normalizedAlgorithm[member] = normalizeAlgorithm(idlValue, 'digest'); |
@@ -971,6 +1019,8 @@ module.exports = { |
971 | 1019 | cleanupWebCryptoResult, |
972 | 1020 | prepareWebCryptoResult, |
973 | 1021 | validateMaxBufferLength, |
| 1022 | + numBitsToBytes, |
| 1023 | + truncateToBitLength, |
974 | 1024 | bigIntArrayToUnsignedBigInt, |
975 | 1025 | bigIntArrayToUnsignedInt, |
976 | 1026 | getBlockSize, |
|
0 commit comments