| 1 | 'use strict';
|
|---|
| 2 |
|
|---|
| 3 | import utils from '../utils.js';
|
|---|
| 4 |
|
|---|
| 5 | function trimSPorHTAB(str) {
|
|---|
| 6 | let start = 0;
|
|---|
| 7 | let end = str.length;
|
|---|
| 8 |
|
|---|
| 9 | while (start < end) {
|
|---|
| 10 | const code = str.charCodeAt(start);
|
|---|
| 11 |
|
|---|
| 12 | if (code !== 0x09 && code !== 0x20) {
|
|---|
| 13 | break;
|
|---|
| 14 | }
|
|---|
| 15 |
|
|---|
| 16 | start += 1;
|
|---|
| 17 | }
|
|---|
| 18 |
|
|---|
| 19 | while (end > start) {
|
|---|
| 20 | const code = str.charCodeAt(end - 1);
|
|---|
| 21 |
|
|---|
| 22 | if (code !== 0x09 && code !== 0x20) {
|
|---|
| 23 | break;
|
|---|
| 24 | }
|
|---|
| 25 |
|
|---|
| 26 | end -= 1;
|
|---|
| 27 | }
|
|---|
| 28 |
|
|---|
| 29 | return start === 0 && end === str.length ? str : str.slice(start, end);
|
|---|
| 30 | }
|
|---|
| 31 |
|
|---|
| 32 | // The control-code ranges are intentional: header sanitization strips C0/DEL bytes.
|
|---|
| 33 | // eslint-disable-next-line no-control-regex
|
|---|
| 34 | const INVALID_UNICODE_HEADER_VALUE_CHARS = new RegExp('[\\u0000-\\u0008\\u000a-\\u001f\\u007f]+', 'g');
|
|---|
| 35 | // eslint-disable-next-line no-control-regex
|
|---|
| 36 | const INVALID_BYTE_STRING_HEADER_VALUE_CHARS = new RegExp('[^\\u0009\\u0020-\\u007e\\u0080-\\u00ff]+', 'g');
|
|---|
| 37 |
|
|---|
| 38 | function sanitizeValue(value, invalidChars) {
|
|---|
| 39 | if (utils.isArray(value)) {
|
|---|
| 40 | return value.map((item) => sanitizeValue(item, invalidChars));
|
|---|
| 41 | }
|
|---|
| 42 |
|
|---|
| 43 | return trimSPorHTAB(String(value).replace(invalidChars, ''));
|
|---|
| 44 | }
|
|---|
| 45 |
|
|---|
| 46 | export const sanitizeHeaderValue = (value) =>
|
|---|
| 47 | sanitizeValue(value, INVALID_UNICODE_HEADER_VALUE_CHARS);
|
|---|
| 48 |
|
|---|
| 49 | export const sanitizeByteStringHeaderValue = (value) =>
|
|---|
| 50 | sanitizeValue(value, INVALID_BYTE_STRING_HEADER_VALUE_CHARS);
|
|---|
| 51 |
|
|---|
| 52 | export function toByteStringHeaderObject(headers) {
|
|---|
| 53 | const byteStringHeaders = Object.create(null);
|
|---|
| 54 |
|
|---|
| 55 | utils.forEach(headers.toJSON(), (value, header) => {
|
|---|
| 56 | byteStringHeaders[header] = sanitizeByteStringHeaderValue(value);
|
|---|
| 57 | });
|
|---|
| 58 |
|
|---|
| 59 | return byteStringHeaders;
|
|---|
| 60 | }
|
|---|