From 22228812214d5a1c2966cd626f43be3576e79290 Mon Sep 17 00:00:00 2001 From: Kevin Gibbons Date: Wed, 24 Jan 2024 16:16:06 -0800 Subject: [PATCH] Normative: avoid quadratic behavior in fromHexInto (#44) --- playground/polyfill-core.mjs | 15 ++++++++------- spec.html | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/playground/polyfill-core.mjs b/playground/polyfill-core.mjs index 1b37bf5..1e2fbb0 100644 --- a/playground/polyfill-core.mjs +++ b/playground/polyfill-core.mjs @@ -257,15 +257,12 @@ export function hexToUint8Array(string, into) { if (typeof string !== 'string') { throw new TypeError('expected string to be a string'); } - if (string.length % 2 !== 0) { - throw new SyntaxError('string should be an even number of characters'); - } - if (/[^0-9a-fA-F]/.test(string)) { - throw new SyntaxError('string should only contain hex characters'); - } if (into && 'detached' in into.buffer && into.buffer.detached) { throw new TypeError('fromHexInto called on array backed by detached buffer'); } + if (string.length % 2 !== 0) { + throw new SyntaxError('string should be an even number of characters'); + } let maxLength = into ? into.length : 2 ** 53 - 1; @@ -275,7 +272,11 @@ export function hexToUint8Array(string, into) { let index = 0; if (maxLength > 0) { while (index < string.length) { - bytes.push(parseInt(string.slice(index, index + 2), 16)); + let hexits = string.slice(index, index + 2); + if (/[^0-9a-fA-F]/.test(hexits)) { + throw new SyntaxError('string should only contain hex characters'); + } + bytes.push(parseInt(hexits, 16)); index += 2; if (bytes.length === maxLength) { break; diff --git a/spec.html b/spec.html index 0a56640..370dd57 100644 --- a/spec.html +++ b/spec.html @@ -330,11 +330,11 @@

1. If _maxLength_ is not present, let _maxLength_ be 253 - 1. 1. Let _length_ be the length of _string_. 1. If _length_ modulo 2 is not 0, throw a *SyntaxError* exception. - 1. If _string_ contains any code units which are not in *"0123456789abcdefABCDEF"*, throw a *SyntaxError* exception. 1. Let _bytes_ be « ». 1. Let _index_ be 0. 1. Repeat, while _index_ < _length_, 1. Let _hexits_ be the substring of _string_ from _index_ to _index_ + 2. + 1. If _hexits_ contains any code units which are not in *"0123456789abcdefABCDEF"*, throw a *SyntaxError* exception. 1. Set _index_ to _index_ + 2. 1. Let _byte_ be the integer value represented by _hexits_ in base-16 notation, using the letters A-F and a-f for digits with values 10 through 15. 1. Append _byte_ to _bytes_.