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