Skip to content

Commit

Permalink
fetch: improve performance of isValidHeaderValue (#3098)
Browse files Browse the repository at this point in the history
  • Loading branch information
Uzlopak committed Apr 12, 2024
1 parent c1c0bd6 commit ca1dbb8
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 17 deletions.
38 changes: 38 additions & 0 deletions benchmarks/fetch/is-valid-header-value.mjs
Original file line number Diff line number Diff line change
@@ -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()
25 changes: 8 additions & 17 deletions lib/web/fetch/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
38 changes: 38 additions & 0 deletions test/fetch/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
})
})

0 comments on commit ca1dbb8

Please sign in to comment.