validation.js (3192B)
1 'use strict'; 2 3 // 4 // Allowed token characters: 5 // 6 // '!', '#', '$', '%', '&', ''', '*', '+', '-', 7 // '.', 0-9, A-Z, '^', '_', '`', a-z, '|', '~' 8 // 9 // tokenChars[32] === 0 // ' ' 10 // tokenChars[33] === 1 // '!' 11 // tokenChars[34] === 0 // '"' 12 // ... 13 // 14 // prettier-ignore 15 const tokenChars = [ 16 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 15 17 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16 - 31 18 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, // 32 - 47 19 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 48 - 63 20 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64 - 79 21 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, // 80 - 95 22 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 96 - 111 23 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0 // 112 - 127 24 ]; 25 26 /** 27 * Checks if a status code is allowed in a close frame. 28 * 29 * @param {Number} code The status code 30 * @return {Boolean} `true` if the status code is valid, else `false` 31 * @public 32 */ 33 function isValidStatusCode(code) { 34 return ( 35 (code >= 1000 && 36 code <= 1014 && 37 code !== 1004 && 38 code !== 1005 && 39 code !== 1006) || 40 (code >= 3000 && code <= 4999) 41 ); 42 } 43 44 /** 45 * Checks if a given buffer contains only correct UTF-8. 46 * Ported from https://www.cl.cam.ac.uk/%7Emgk25/ucs/utf8_check.c by 47 * Markus Kuhn. 48 * 49 * @param {Buffer} buf The buffer to check 50 * @return {Boolean} `true` if `buf` contains only correct UTF-8, else `false` 51 * @public 52 */ 53 function _isValidUTF8(buf) { 54 const len = buf.length; 55 let i = 0; 56 57 while (i < len) { 58 if ((buf[i] & 0x80) === 0) { 59 // 0xxxxxxx 60 i++; 61 } else if ((buf[i] & 0xe0) === 0xc0) { 62 // 110xxxxx 10xxxxxx 63 if ( 64 i + 1 === len || 65 (buf[i + 1] & 0xc0) !== 0x80 || 66 (buf[i] & 0xfe) === 0xc0 // Overlong 67 ) { 68 return false; 69 } 70 71 i += 2; 72 } else if ((buf[i] & 0xf0) === 0xe0) { 73 // 1110xxxx 10xxxxxx 10xxxxxx 74 if ( 75 i + 2 >= len || 76 (buf[i + 1] & 0xc0) !== 0x80 || 77 (buf[i + 2] & 0xc0) !== 0x80 || 78 (buf[i] === 0xe0 && (buf[i + 1] & 0xe0) === 0x80) || // Overlong 79 (buf[i] === 0xed && (buf[i + 1] & 0xe0) === 0xa0) // Surrogate (U+D800 - U+DFFF) 80 ) { 81 return false; 82 } 83 84 i += 3; 85 } else if ((buf[i] & 0xf8) === 0xf0) { 86 // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 87 if ( 88 i + 3 >= len || 89 (buf[i + 1] & 0xc0) !== 0x80 || 90 (buf[i + 2] & 0xc0) !== 0x80 || 91 (buf[i + 3] & 0xc0) !== 0x80 || 92 (buf[i] === 0xf0 && (buf[i + 1] & 0xf0) === 0x80) || // Overlong 93 (buf[i] === 0xf4 && buf[i + 1] > 0x8f) || 94 buf[i] > 0xf4 // > U+10FFFF 95 ) { 96 return false; 97 } 98 99 i += 4; 100 } else { 101 return false; 102 } 103 } 104 105 return true; 106 } 107 108 module.exports = { 109 isValidStatusCode, 110 isValidUTF8: _isValidUTF8, 111 tokenChars 112 }; 113 114 /* istanbul ignore else */ 115 if (!process.env.WS_NO_UTF_8_VALIDATE) { 116 try { 117 const isValidUTF8 = require('utf-8-validate'); 118 119 module.exports.isValidUTF8 = function (buf) { 120 return buf.length < 150 ? _isValidUTF8(buf) : isValidUTF8(buf); 121 }; 122 } catch (e) { 123 // Continue regardless of the error. 124 } 125 }