diff --git a/benchmarks/fetch/is-valid-header-value.mjs b/benchmarks/fetch/is-valid-header-value.mjs new file mode 100644 index 00000000000..60a9a54b6cb --- /dev/null +++ b/benchmarks/fetch/is-valid-header-value.mjs @@ -0,0 +1,38 @@ +import { bench, run } from 'mitata' +import { isValidHeaderValue } from '../../lib/web/fetch/util.js' + +const valid = 'valid123' +const invalidNUL = 'invalid\x00' +const invalidCR = 'invalid\r' +const invalidLF = 'invalid\n' +const invalidTrailingTab = 'invalid\t' +const invalidLeadingTab = '\tinvalid' +const invalidTrailingSpace = 'invalid ' +const invalidLeadingSpace = ' invalid' + +bench('isValidHeaderValue valid', () => { + isValidHeaderValue(valid) +}) +bench('isValidHeaderValue invalid containing NUL', () => { + isValidHeaderValue(invalidNUL) +}) +bench('isValidHeaderValue invalid containing CR', () => { + isValidHeaderValue(invalidCR) +}) +bench('isValidHeaderValue invalid containing LF', () => { + isValidHeaderValue(invalidLF) +}) +bench('isValidHeaderValue invalid trailing TAB', () => { + isValidHeaderValue(invalidTrailingTab) +}) +bench('isValidHeaderValue invalid leading TAB', () => { + isValidHeaderValue(invalidLeadingTab) +}) +bench('isValidHeaderValue invalid trailing SPACE', () => { + isValidHeaderValue(invalidTrailingSpace) +}) +bench('isValidHeaderValue invalid leading SPACE', () => { + isValidHeaderValue(invalidLeadingSpace) +}) + +await run() diff --git a/lib/web/fetch/util.js b/lib/web/fetch/util.js index b7b9602bdbf..7dd56c1d5c1 100644 --- a/lib/web/fetch/util.js +++ b/lib/web/fetch/util.js @@ -159,24 +159,15 @@ const isValidHeaderName = isValidHTTPToken function isValidHeaderValue (potentialValue) { // - Has no leading or trailing HTTP tab or space bytes. // - Contains no 0x00 (NUL) or HTTP newline bytes. - if ( - potentialValue.startsWith('\t') || - potentialValue.startsWith(' ') || - potentialValue.endsWith('\t') || - potentialValue.endsWith(' ') - ) { - return false - } - - if ( - potentialValue.includes('\0') || + return ( + potentialValue[0] === '\t' || + potentialValue[0] === ' ' || + potentialValue[potentialValue.length - 1] === '\t' || + potentialValue[potentialValue.length - 1] === ' ' || + potentialValue.includes('\n') || potentialValue.includes('\r') || - potentialValue.includes('\n') - ) { - return false - } - - return true + potentialValue.includes('\0') + ) === false } // https://w3c.github.io/webappsec-referrer-policy/#set-requests-referrer-policy-on-redirect diff --git a/test/fetch/util.js b/test/fetch/util.js index bb9103facd3..da4c2d90cc1 100644 --- a/test/fetch/util.js +++ b/test/fetch/util.js @@ -355,3 +355,41 @@ describe('urlHasHttpsScheme', () => { assert.strictEqual(urlHasHttpsScheme({ protocol: 'https:' }), true) }) }) + +describe('isValidHeaderValue', () => { + const { isValidHeaderValue } = util + + test('should return true for valid string', () => { + assert.strictEqual(isValidHeaderValue('valid123'), true) + assert.strictEqual(isValidHeaderValue('va lid123'), true) + assert.strictEqual(isValidHeaderValue('va\tlid123'), true) + }) + test('should return false for string containing NUL', () => { + assert.strictEqual(isValidHeaderValue('invalid\0'), false) + assert.strictEqual(isValidHeaderValue('in\0valid'), false) + assert.strictEqual(isValidHeaderValue('\0invalid'), false) + }) + test('should return false for string containing CR', () => { + assert.strictEqual(isValidHeaderValue('invalid\r'), false) + assert.strictEqual(isValidHeaderValue('in\rvalid'), false) + assert.strictEqual(isValidHeaderValue('\rinvalid'), false) + }) + test('should return false for string containing LF', () => { + assert.strictEqual(isValidHeaderValue('invalid\n'), false) + assert.strictEqual(isValidHeaderValue('in\nvalid'), false) + assert.strictEqual(isValidHeaderValue('\ninvalid'), false) + }) + + test('should return false for string with leading TAB', () => { + assert.strictEqual(isValidHeaderValue('\tinvalid'), false) + }) + test('should return false for string with trailing TAB', () => { + assert.strictEqual(isValidHeaderValue('invalid\t'), false) + }) + test('should return false for string with leading SPACE', () => { + assert.strictEqual(isValidHeaderValue(' invalid'), false) + }) + test('should return false for string with trailing SPACE', () => { + assert.strictEqual(isValidHeaderValue('invalid '), false) + }) +})