| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 8bb5360 commit 1ebbbd5
2 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -106,6 +106,22 @@ converters['sequence<KeyUsage>'] = createSequenceConverter(converters.KeyUsage); | |||
| 106 | 106 | ||
| 107 | 107 | converters.HashAlgorithmIdentifier = converters.AlgorithmIdentifier; | |
| 108 | 108 | ||
| 109 | + /** | ||
| 110 | + * Builds conversion options for Web Crypto integer members that use Web IDL | ||
| 111 | + * [EnforceRange]. Keep this helper instead of spreading opts in each member | ||
| 112 | + * converter so the hot dictionary paths allocate stable-shape objects. | ||
| 113 | + * @param {object} opts Parent conversion options. | ||
| 114 | + * @returns {object} | ||
| 115 | + */ | ||
| 116 | + function enforceRangeOptions(opts) { | ||
| 117 | + return { | ||
| 118 | + prefix: opts.prefix, | ||
| 119 | + context: opts.context, | ||
| 120 | + code: opts.code, | ||
| 121 | + enforceRange: true, | ||
| 122 | + }; | ||
| 123 | + } | ||
| 124 | + | ||
| 109 | 125 | const dictAlgorithm = [ | |
| 110 | 126 | { | |
| 111 | 127 | key: 'name', | |
@@ -121,8 +137,9 @@ converters.Algorithm = createDictionaryConverter( | |||
| 121 | 137 | // converters.BigInteger = webidl.Uint8Array; | |
| 122 | 138 | converters.BigInteger = (V, opts = kEmptyObject) => { | |
| 123 | 139 | return webidl.Uint8Array(V, { | |
| 124 | - __proto__: null, | ||
| 125 | - ...opts, | ||
| 140 | + prefix: opts.prefix, | ||
| 141 | + context: opts.context, | ||
| 142 | + code: opts.code, | ||
| 126 | 143 | allowResizable: true, | |
| 127 | 144 | allowShared: false, | |
| 128 | 145 | }); | |
@@ -132,18 +149,20 @@ converters.BigInteger = (V, opts = kEmptyObject) => { | |||
| 132 | 149 | // removing this altogether. | |
| 133 | 150 | converters.BufferSource = (V, opts = kEmptyObject) => { | |
| 134 | 151 | return webidl.BufferSource(V, { | |
| 135 | - __proto__: null, | ||
| 136 | - ...opts, | ||
| 152 | + prefix: opts.prefix, | ||
| 153 | + context: opts.context, | ||
| 154 | + code: opts.code, | ||
| 137 | 155 | allowResizable: opts.allowResizable === undefined ? | |
| 138 | 156 | true : opts.allowResizable, | |
| 157 | + allowShared: opts.allowShared, | ||
| 139 | 158 | }); | |
| 140 | 159 | }; | |
| 141 | 160 | ||
| 142 | 161 | const dictRsaKeyGenParams = [ | |
| 143 | 162 | { | |
| 144 | 163 | key: 'modulusLength', | |
| 145 | 164 | converter: (V, opts) => | |
| 146 | - converters['unsigned long'](V, { ...opts, enforceRange: true }), | ||
| 165 | + converters['unsigned long'](V, enforceRangeOptions(opts)), | ||
| 147 | 166 | required: true, | |
| 148 | 167 | }, | |
| 149 | 168 | { | |
@@ -221,7 +240,7 @@ converters.AesKeyGenParams = createDictionaryConverter( | |||
| 221 | 240 | { | |
| 222 | 241 | key: 'length', | |
| 223 | 242 | converter: (V, opts) => | |
| 224 | - converters['unsigned short'](V, { ...opts, enforceRange: true }), | ||
| 243 | + converters['unsigned short'](V, enforceRangeOptions(opts)), | ||
| 225 | 244 | validator: AESLengthValidator, | |
| 226 | 245 | required: true, | |
| 227 | 246 | }, | |
@@ -244,7 +263,7 @@ converters.RsaPssParams = createDictionaryConverter( | |||
| 244 | 263 | { | |
| 245 | 264 | key: 'saltLength', | |
| 246 | 265 | converter: (V, opts) => | |
| 247 | - converters['unsigned long'](V, { ...opts, enforceRange: true }), | ||
| 266 | + converters['unsigned long'](V, enforceRangeOptions(opts)), | ||
| 248 | 267 | required: true, | |
| 249 | 268 | }, | |
| 250 | 269 | ], | |
@@ -288,7 +307,7 @@ for (const { 0: name, 1: zeroError } of [['HmacKeyGenParams', 'OperationError'], | |||
| 288 | 307 | { | |
| 289 | 308 | key: 'length', | |
| 290 | 309 | converter: (V, opts) => | |
| 291 | - converters['unsigned long'](V, { ...opts, enforceRange: true }), | ||
| 310 | + converters['unsigned long'](V, enforceRangeOptions(opts)), | ||
| 292 | 311 | validator: validateMacKeyLength(`${name}.length`, zeroError), | |
| 293 | 312 | }, | |
| 294 | 313 | ], | |
@@ -370,7 +389,7 @@ converters.CShakeParams = createDictionaryConverter( | |||
| 370 | 389 | { | |
| 371 | 390 | key: 'outputLength', | |
| 372 | 391 | converter: (V, opts) => | |
| 373 | - converters['unsigned long'](V, { ...opts, enforceRange: true }), | ||
| 392 | + converters['unsigned long'](V, enforceRangeOptions(opts)), | ||
| 374 | 393 | validator: (V, opts) => { | |
| 375 | 394 | // The Web Crypto spec allows for SHAKE output length that are not multiples of | |
| 376 | 395 | // 8. We don't. | |
@@ -404,7 +423,7 @@ converters.Pbkdf2Params = createDictionaryConverter( | |||
| 404 | 423 | { | |
| 405 | 424 | key: 'iterations', | |
| 406 | 425 | converter: (V, opts) => | |
| 407 | - converters['unsigned long'](V, { ...opts, enforceRange: true }), | ||
| 426 | + converters['unsigned long'](V, enforceRangeOptions(opts)), | ||
| 408 | 427 | validator: (V, dict) => { | |
| 409 | 428 | if (V === 0) | |
| 410 | 429 | throw lazyDOMException('iterations cannot be zero', 'OperationError'); | |
@@ -427,7 +446,7 @@ converters.AesDerivedKeyParams = createDictionaryConverter( | |||
| 427 | 446 | { | |
| 428 | 447 | key: 'length', | |
| 429 | 448 | converter: (V, opts) => | |
| 430 | - converters['unsigned short'](V, { ...opts, enforceRange: true }), | ||
| 449 | + converters['unsigned short'](V, enforceRangeOptions(opts)), | ||
| 431 | 450 | validator: AESLengthValidator, | |
| 432 | 451 | required: true, | |
| 433 | 452 | }, | |
@@ -481,7 +500,7 @@ converters.AeadParams = createDictionaryConverter( | |||
| 481 | 500 | { | |
| 482 | 501 | key: 'tagLength', | |
| 483 | 502 | converter: (V, opts) => | |
| 484 | - converters.octet(V, { ...opts, enforceRange: true }), | ||
| 503 | + converters.octet(V, enforceRangeOptions(opts)), | ||
| 485 | 504 | validator: (V, dict) => { | |
| 486 | 505 | switch (StringPrototypeToLowerCase(dict.name)) { | |
| 487 | 506 | case 'chacha20-poly1305': | |
@@ -524,7 +543,7 @@ converters.AesCtrParams = createDictionaryConverter( | |||
| 524 | 543 | { | |
| 525 | 544 | key: 'length', | |
| 526 | 545 | converter: (V, opts) => | |
| 527 | - converters.octet(V, { ...opts, enforceRange: true }), | ||
| 546 | + converters.octet(V, enforceRangeOptions(opts)), | ||
| 528 | 547 | validator: (V, dict) => { | |
| 529 | 548 | if (V === 0 || V > 128) | |
| 530 | 549 | throw lazyDOMException( | |
@@ -604,7 +623,7 @@ converters.Argon2Params = createDictionaryConverter( | |||
| 604 | 623 | { | |
| 605 | 624 | key: 'parallelism', | |
| 606 | 625 | converter: (V, opts) => | |
| 607 | - converters['unsigned long'](V, { ...opts, enforceRange: true }), | ||
| 626 | + converters['unsigned long'](V, enforceRangeOptions(opts)), | ||
| 608 | 627 | validator: (V, dict) => { | |
| 609 | 628 | if (V === 0 || V > MathPow(2, 24) - 1) { | |
| 610 | 629 | throw lazyDOMException( | |
@@ -617,7 +636,7 @@ converters.Argon2Params = createDictionaryConverter( | |||
| 617 | 636 | { | |
| 618 | 637 | key: 'memory', | |
| 619 | 638 | converter: (V, opts) => | |
| 620 | - converters['unsigned long'](V, { ...opts, enforceRange: true }), | ||
| 639 | + converters['unsigned long'](V, enforceRangeOptions(opts)), | ||
| 621 | 640 | validator: (V, dict) => { | |
| 622 | 641 | if (V < 8 * dict.parallelism) { | |
| 623 | 642 | throw lazyDOMException( | |
@@ -630,7 +649,7 @@ converters.Argon2Params = createDictionaryConverter( | |||
| 630 | 649 | { | |
| 631 | 650 | key: 'passes', | |
| 632 | 651 | converter: (V, opts) => | |
| 633 | - converters['unsigned long'](V, { ...opts, enforceRange: true }), | ||
| 652 | + converters['unsigned long'](V, enforceRangeOptions(opts)), | ||
| 634 | 653 | validator: (V) => { | |
| 635 | 654 | if (V === 0) { | |
| 636 | 655 | throw lazyDOMException('passes must be > 0', 'OperationError'); | |
@@ -641,7 +660,7 @@ converters.Argon2Params = createDictionaryConverter( | |||
| 641 | 660 | { | |
| 642 | 661 | key: 'version', | |
| 643 | 662 | converter: (V, opts) => | |
| 644 | - converters.octet(V, { ...opts, enforceRange: true }), | ||
| 663 | + converters.octet(V, enforceRangeOptions(opts)), | ||
| 645 | 664 | validator: (V, dict) => { | |
| 646 | 665 | if (V !== 0x13) { | |
| 647 | 666 | throw lazyDOMException( | |
@@ -680,7 +699,7 @@ for (const { 0: name, 1: zeroError } of [['KmacKeyGenParams', 'OperationError'], | |||
| 680 | 699 | { | |
| 681 | 700 | key: 'length', | |
| 682 | 701 | converter: (V, opts) => | |
| 683 | - converters['unsigned long'](V, { ...opts, enforceRange: true }), | ||
| 702 | + converters['unsigned long'](V, enforceRangeOptions(opts)), | ||
| 684 | 703 | validator: validateMacKeyLength(`${name}.length`, zeroError), | |
| 685 | 704 | }, | |
| 686 | 705 | ], | |
@@ -694,7 +713,7 @@ converters.KmacParams = createDictionaryConverter( | |||
| 694 | 713 | { | |
| 695 | 714 | key: 'outputLength', | |
| 696 | 715 | converter: (V, opts) => | |
| 697 | - converters['unsigned long'](V, { ...opts, enforceRange: true }), | ||
| 716 | + converters['unsigned long'](V, enforceRangeOptions(opts)), | ||
| 698 | 717 | validator: (V, opts) => { | |
| 699 | 718 | // The Web Crypto spec allows for KMAC output length that are not multiples of 8. We don't. | |
| 700 | 719 | if (V % 8) | |
@@ -716,7 +735,7 @@ converters.KangarooTwelveParams = createDictionaryConverter( | |||
| 716 | 735 | { | |
| 717 | 736 | key: 'outputLength', | |
| 718 | 737 | converter: (V, opts) => | |
| 719 | - converters['unsigned long'](V, { ...opts, enforceRange: true }), | ||
| 738 | + converters['unsigned long'](V, enforceRangeOptions(opts)), | ||
| 720 | 739 | validator: (V, opts) => { | |
| 721 | 740 | if (V === 0 || V % 8) | |
| 722 | 741 | throw lazyDOMException('Invalid KangarooTwelveParams outputLength', 'OperationError'); | |
@@ -737,7 +756,7 @@ converters.TurboShakeParams = createDictionaryConverter( | |||
| 737 | 756 | { | |
| 738 | 757 | key: 'outputLength', | |
| 739 | 758 | converter: (V, opts) => | |
| 740 | - converters['unsigned long'](V, { ...opts, enforceRange: true }), | ||
| 759 | + converters['unsigned long'](V, enforceRangeOptions(opts)), | ||
| 741 | 760 | validator: (V, opts) => { | |
| 742 | 761 | if (V === 0 || V % 8) | |
| 743 | 762 | throw lazyDOMException('Invalid TurboShakeParams outputLength', 'OperationError'); | |
@@ -747,7 +766,7 @@ converters.TurboShakeParams = createDictionaryConverter( | |||
| 747 | 766 | { | |
| 748 | 767 | key: 'domainSeparation', | |
| 749 | 768 | converter: (V, opts) => | |
| 750 | - converters.octet(V, { ...opts, enforceRange: true }), | ||
| 769 | + converters.octet(V, enforceRangeOptions(opts)), | ||
| 751 | 770 | validator: (V) => { | |
| 752 | 771 | if (V < 0x01 || V > 0x7F) { | |
| 753 | 772 | throw lazyDOMException( | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -109,6 +109,28 @@ function makeException(message, options = kEmptyObject) { | |||
| 109 | 109 | ); | |
| 110 | 110 | } | |
| 111 | 111 | ||
| 112 | + /** | ||
| 113 | + * Builds derived conversion options for nested converter calls and adjusted | ||
| 114 | + * error codes. These objects are allocated on dictionary/sequence conversion | ||
| 115 | + * hot paths, so keep their shape stable and avoid object spread and | ||
| 116 | + * null-prototype objects. | ||
| 117 | + * @param {ConversionOptions} options Parent conversion options. | ||
| 118 | + * @param {string} [context] Replacement context. | ||
| 119 | + * @param {string} [code] Replacement error code. | ||
| 120 | + * @returns {ConversionOptions} | ||
| 121 | + */ | ||
| 122 | + function makeOptions(options, context = options.context, code = options.code) { | ||
| 123 | + return { | ||
| 124 | + prefix: options.prefix, | ||
| 125 | + context, | ||
| 126 | + code, | ||
| 127 | + enforceRange: options.enforceRange, | ||
| 128 | + clamp: options.clamp, | ||
| 129 | + allowShared: options.allowShared, | ||
| 130 | + allowResizable: options.allowResizable, | ||
| 131 | + }; | ||
| 132 | + } | ||
| 133 | + | ||
| 112 | 134 | /** | |
| 113 | 135 | * Returns the ECMAScript specification type of a JavaScript value. | |
| 114 | 136 | * @see https://tc39.es/ecma262/#sec-ecmascript-data-types-and-values | |
@@ -376,7 +398,7 @@ function convertToInt( | |||
| 376 | 398 | if (integer < lowerBound || integer > upperBound) { | |
| 377 | 399 | throw makeException( | |
| 378 | 400 | `is outside the expected range of ${lowerBound} to ${upperBound}.`, | |
| 379 | - { __proto__: null, ...options, code: 'ERR_OUT_OF_RANGE' }); | ||
| 401 | + makeOptions(options, options.context, 'ERR_OUT_OF_RANGE')); | ||
| 380 | 402 | } | |
| 381 | 403 | ||
| 382 | 404 | return integer; | |
@@ -416,7 +438,7 @@ function convertToInt( | |||
| 416 | 438 | if (x < lowerBound || x > upperBound) { | |
| 417 | 439 | throw makeException( | |
| 418 | 440 | `is outside the expected range of ${lowerBound} to ${upperBound}.`, | |
| 419 | - { __proto__: null, ...options, code: 'ERR_OUT_OF_RANGE' }); | ||
| 441 | + makeOptions(options, options.context, 'ERR_OUT_OF_RANGE')); | ||
| 420 | 442 | } | |
| 421 | 443 | ||
| 422 | 444 | return x; | |
@@ -593,7 +615,7 @@ function requiredArguments(length, required, options = kEmptyObject) { | |||
| 593 | 615 | `${required} argument${ | |
| 594 | 616 | required === 1 ? '' : 's' | |
| 595 | 617 | } required, but only ${length} present.`, | |
| 596 | - { __proto__: null, ...options, context: '', code: 'ERR_MISSING_ARGS' }); | ||
| 618 | + makeOptions(options, '', 'ERR_MISSING_ARGS')); | ||
| 597 | 619 | } | |
| 598 | 620 | } | |
| 599 | 621 | ||
@@ -615,7 +637,7 @@ function createEnumConverter(name, values) { | |||
| 615 | 637 | if (!E.has(S)) { | |
| 616 | 638 | throw makeException( | |
| 617 | 639 | `'${S}' is not a valid enum value of type ${name}.`, | |
| 618 | - { __proto__: null, ...options, code: 'ERR_INVALID_ARG_VALUE' }); | ||
| 640 | + makeOptions(options, options.context, 'ERR_INVALID_ARG_VALUE')); | ||
| 619 | 641 | } | |
| 620 | 642 | ||
| 621 | 643 | // Step 3: return the matching enumeration value. | |
@@ -715,11 +737,7 @@ function createDictionaryConverter( | |||
| 715 | 737 | // Step 4.1.4.1: convert the JavaScript value to IDL. | |
| 716 | 738 | const idlMemberValue = converter( | |
| 717 | 739 | jsMemberValue, | |
| 718 | - { | ||
| 719 | - __proto__: null, | ||
| 720 | - ...options, | ||
| 721 | - context: dictionaryMemberContext(key, options), | ||
| 722 | - }, | ||
| 740 | + makeOptions(options, dictionaryMemberContext(key, options)), | ||
| 723 | 741 | ); | |
| 724 | 742 | // Validators are a Node.js extension after conversion. They let | |
| 725 | 743 | // consumers reject known unsupported values while dictionary | |
@@ -736,7 +754,7 @@ function createDictionaryConverter( | |||
| 736 | 754 | // Step 4.1.6: required missing members throw. | |
| 737 | 755 | throw makeException( | |
| 738 | 756 | missingDictionaryMemberMessage(dictionaryName, key), | |
| 739 | - { __proto__: null, ...options, code: 'ERR_MISSING_OPTION' }); | ||
| 757 | + makeOptions(options, options.context, 'ERR_MISSING_OPTION')); | ||
| 740 | 758 | } | |
| 741 | 759 | } | |
| 742 | 760 | } | |
@@ -794,11 +812,10 @@ function createSequenceConverter(converter) { | |||
| 794 | 812 | break; | |
| 795 | 813 | } | |
| 796 | 814 | // Step 3.3: convert next to an IDL value of type T. | |
| 797 | - const idlValue = converter(next.value, { | ||
| 798 | - __proto__: null, | ||
| 799 | - ...options, | ||
| 800 | - context: sequenceElementContext(idlSequence.length, options), | ||
| 801 | - }); | ||
| 815 | + const idlValue = converter( | ||
| 816 | + next.value, | ||
| 817 | + makeOptions(options, sequenceElementContext(idlSequence.length, options)), | ||
| 818 | + ); | ||
| 802 | 819 | // Step 3.4: store the value and advance i. | |
| 803 | 820 | ArrayPrototypePush(idlSequence, idlValue); | |
| 804 | 821 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments