|
| 1 | +'use strict'; |
| 2 | +const common = require('../common'); |
| 3 | +const assert = require('assert'); |
| 4 | + |
| 5 | +const Buffer = require('buffer').Buffer; |
| 6 | + |
| 7 | +const b = new Buffer('abcdef'); |
| 8 | +const buf_a = new Buffer('a'); |
| 9 | +const buf_bc = new Buffer('bc'); |
| 10 | +const buf_f = new Buffer('f'); |
| 11 | +const buf_z = new Buffer('z'); |
| 12 | +const buf_empty = new Buffer(''); |
| 13 | + |
| 14 | +assert(b.includes('a')); |
| 15 | +assert(!b.includes('a', 1)); |
| 16 | +assert(!b.includes('a', -1)); |
| 17 | +assert(!b.includes('a', -4)); |
| 18 | +assert(b.includes('a', -b.length)); |
| 19 | +assert(b.includes('a', NaN)); |
| 20 | +assert(b.includes('a', -Infinity)); |
| 21 | +assert(!b.includes('a', Infinity)); |
| 22 | +assert(b.includes('bc')); |
| 23 | +assert(!b.includes('bc', 2)); |
| 24 | +assert(!b.includes('bc', -1)); |
| 25 | +assert(!b.includes('bc', -3)); |
| 26 | +assert(b.includes('bc', -5)); |
| 27 | +assert(b.includes('bc', NaN)); |
| 28 | +assert(b.includes('bc', -Infinity)); |
| 29 | +assert(!b.includes('bc', Infinity)); |
| 30 | +assert(b.includes('f'), b.length - 1); |
| 31 | +assert(!b.includes('z')); |
| 32 | +assert(!b.includes('')); |
| 33 | +assert(!b.includes('', 1)); |
| 34 | +assert(!b.includes('', b.length + 1)); |
| 35 | +assert(!b.includes('', Infinity)); |
| 36 | +assert(b.includes(buf_a)); |
| 37 | +assert(!b.includes(buf_a, 1)); |
| 38 | +assert(!b.includes(buf_a, -1)); |
| 39 | +assert(!b.includes(buf_a, -4)); |
| 40 | +assert(b.includes(buf_a, -b.length)); |
| 41 | +assert(b.includes(buf_a, NaN)); |
| 42 | +assert(b.includes(buf_a, -Infinity)); |
| 43 | +assert(!b.includes(buf_a, Infinity)); |
| 44 | +assert(b.includes(buf_bc)); |
| 45 | +assert(!b.includes(buf_bc, 2)); |
| 46 | +assert(!b.includes(buf_bc, -1)); |
| 47 | +assert(!b.includes(buf_bc, -3)); |
| 48 | +assert(b.includes(buf_bc, -5)); |
| 49 | +assert(b.includes(buf_bc, NaN)); |
| 50 | +assert(b.includes(buf_bc, -Infinity)); |
| 51 | +assert(!b.includes(buf_bc, Infinity)); |
| 52 | +assert(b.includes(buf_f), b.length - 1); |
| 53 | +assert(!b.includes(buf_z)); |
| 54 | +assert(!b.includes(buf_empty)); |
| 55 | +assert(!b.includes(buf_empty, 1)); |
| 56 | +assert(!b.includes(buf_empty, b.length + 1)); |
| 57 | +assert(!b.includes(buf_empty, Infinity)); |
| 58 | +assert(b.includes(0x61)); |
| 59 | +assert(!b.includes(0x61, 1)); |
| 60 | +assert(!b.includes(0x61, -1)); |
| 61 | +assert(!b.includes(0x61, -4)); |
| 62 | +assert(b.includes(0x61, -b.length)); |
| 63 | +assert(b.includes(0x61, NaN)); |
| 64 | +assert(b.includes(0x61, -Infinity)); |
| 65 | +assert(!b.includes(0x61, Infinity)); |
| 66 | +assert(!b.includes(0x0)); |
| 67 | + |
| 68 | +// test offsets |
| 69 | +assert(b.includes('d', 2)); |
| 70 | +assert(b.includes('f', 5)); |
| 71 | +assert(b.includes('f', -1)); |
| 72 | +assert(!b.includes('f', 6)); |
| 73 | + |
| 74 | +assert(b.includes(Buffer('d'), 2)); |
| 75 | +assert(b.includes(Buffer('f'), 5)); |
| 76 | +assert(b.includes(Buffer('f'), -1)); |
| 77 | +assert(!b.includes(Buffer('f'), 6)); |
| 78 | + |
| 79 | +assert(!Buffer('ff').includes(Buffer('f'), 1, 'ucs2')); |
| 80 | + |
| 81 | +// test hex encoding |
| 82 | +assert( |
| 83 | + Buffer(b.toString('hex'), 'hex') |
| 84 | + .includes('64', 0, 'hex')); |
| 85 | +assert( |
| 86 | + Buffer(b.toString('hex'), 'hex') |
| 87 | + .includes(Buffer('64', 'hex'), 0, 'hex')); |
| 88 | + |
| 89 | +// test base64 encoding |
| 90 | +assert( |
| 91 | + Buffer(b.toString('base64'), 'base64') |
| 92 | + .includes('ZA==', 0, 'base64')); |
| 93 | +assert( |
| 94 | + Buffer(b.toString('base64'), 'base64') |
| 95 | + .includes(Buffer('ZA==', 'base64'), 0, 'base64')); |
| 96 | + |
| 97 | +// test ascii encoding |
| 98 | +assert( |
| 99 | + Buffer(b.toString('ascii'), 'ascii') |
| 100 | + .includes('d', 0, 'ascii')); |
| 101 | +assert( |
| 102 | + Buffer(b.toString('ascii'), 'ascii') |
| 103 | + .includes(Buffer('d', 'ascii'), 0, 'ascii')); |
| 104 | + |
| 105 | +// test binary encoding |
| 106 | +assert( |
| 107 | + Buffer(b.toString('binary'), 'binary') |
| 108 | + .includes('d', 0, 'binary')); |
| 109 | +assert( |
| 110 | + Buffer(b.toString('binary'), 'binary') |
| 111 | + .includes(Buffer('d', 'binary'), 0, 'binary')); |
| 112 | + |
| 113 | + |
| 114 | +// test usc2 encoding |
| 115 | +var twoByteString = new Buffer('\u039a\u0391\u03a3\u03a3\u0395', 'ucs2'); |
| 116 | + |
| 117 | +assert(twoByteString.includes('\u0395', 4, 'ucs2')); |
| 118 | +assert(twoByteString.includes('\u03a3', -4, 'ucs2')); |
| 119 | +assert(twoByteString.includes('\u03a3', -6, 'ucs2')); |
| 120 | +assert(twoByteString.includes( |
| 121 | + new Buffer('\u03a3', 'ucs2'), -6, 'ucs2')); |
| 122 | +assert(!twoByteString.includes('\u03a3', -2, 'ucs2')); |
| 123 | + |
| 124 | +const mixedByteStringUcs2 = |
| 125 | + new Buffer('\u039a\u0391abc\u03a3\u03a3\u0395', 'ucs2'); |
| 126 | +assert(mixedByteStringUcs2.includes('bc', 0, 'ucs2')); |
| 127 | +assert(mixedByteStringUcs2.includes('\u03a3', 0, 'ucs2')); |
| 128 | +assert(!mixedByteStringUcs2.includes('\u0396', 0, 'ucs2')); |
| 129 | + |
| 130 | +assert( |
| 131 | + 6, mixedByteStringUcs2.includes(new Buffer('bc', 'ucs2'), 0, 'ucs2')); |
| 132 | +assert( |
| 133 | + 10, mixedByteStringUcs2.includes(new Buffer('\u03a3', 'ucs2'), 0, 'ucs2')); |
| 134 | +assert( |
| 135 | + -1, mixedByteStringUcs2.includes(new Buffer('\u0396', 'ucs2'), 0, 'ucs2')); |
| 136 | + |
| 137 | +twoByteString = new Buffer('\u039a\u0391\u03a3\u03a3\u0395', 'ucs2'); |
| 138 | + |
| 139 | +// Test single char pattern |
| 140 | +assert(twoByteString.includes('\u039a', 0, 'ucs2')); |
| 141 | +assert(twoByteString.includes('\u0391', 0, 'ucs2'), 'Alpha'); |
| 142 | +assert(twoByteString.includes('\u03a3', 0, 'ucs2'), 'First Sigma'); |
| 143 | +assert(twoByteString.includes('\u03a3', 6, 'ucs2'), 'Second Sigma'); |
| 144 | +assert(twoByteString.includes('\u0395', 0, 'ucs2'), 'Epsilon'); |
| 145 | +assert(!twoByteString.includes('\u0392', 0, 'ucs2'), 'Not beta'); |
| 146 | + |
| 147 | +// Test multi-char pattern |
| 148 | +assert(twoByteString.includes('\u039a\u0391', 0, 'ucs2'), 'Lambda Alpha'); |
| 149 | +assert(twoByteString.includes('\u0391\u03a3', 0, 'ucs2'), 'Alpha Sigma'); |
| 150 | +assert(twoByteString.includes('\u03a3\u03a3', 0, 'ucs2'), 'Sigma Sigma'); |
| 151 | +assert(twoByteString.includes('\u03a3\u0395', 0, 'ucs2'), 'Sigma Epsilon'); |
| 152 | + |
| 153 | +const mixedByteStringUtf8 = new Buffer('\u039a\u0391abc\u03a3\u03a3\u0395'); |
| 154 | +assert(mixedByteStringUtf8.includes('bc')); |
| 155 | +assert(mixedByteStringUtf8.includes('bc', 5)); |
| 156 | +assert(mixedByteStringUtf8.includes('bc', -8)); |
| 157 | +assert(mixedByteStringUtf8.includes('\u03a3')); |
| 158 | +assert(!mixedByteStringUtf8.includes('\u0396')); |
| 159 | + |
| 160 | + |
| 161 | +// Test complex string includes algorithms. Only trigger for long strings. |
| 162 | +// Long string that isn't a simple repeat of a shorter string. |
| 163 | +var longString = 'A'; |
| 164 | +for (var i = 66; i < 76; i++) { // from 'B' to 'K' |
| 165 | + longString = longString + String.fromCharCode(i) + longString; |
| 166 | +} |
| 167 | + |
| 168 | +const longBufferString = new Buffer(longString); |
| 169 | + |
| 170 | +// pattern of 15 chars, repeated every 16 chars in long |
| 171 | +var pattern = 'ABACABADABACABA'; |
| 172 | +for (var i = 0; i < longBufferString.length - pattern.length; i += 7) { |
| 173 | + const includes = longBufferString.includes(pattern, i); |
| 174 | + assert(includes, 'Long ABACABA...-string at index ' + i); |
| 175 | +} |
| 176 | +assert(longBufferString.includes('AJABACA'), 'Long AJABACA, First J'); |
| 177 | +assert(longBufferString.includes('AJABACA', 511), 'Long AJABACA, Second J'); |
| 178 | + |
| 179 | +pattern = 'JABACABADABACABA'; |
| 180 | +assert(longBufferString.includes(pattern), 'Long JABACABA..., First J'); |
| 181 | +assert(longBufferString.includes(pattern, 512), 'Long JABACABA..., Second J'); |
| 182 | + |
| 183 | +// Search for a non-ASCII string in a pure ASCII string. |
| 184 | +const asciiString = new Buffer( |
| 185 | + 'arglebargleglopglyfarglebargleglopglyfarglebargleglopglyf'); |
| 186 | +assert(!asciiString.includes('\x2061')); |
| 187 | +assert(asciiString.includes('leb', 0)); |
| 188 | + |
| 189 | +// Search in string containing many non-ASCII chars. |
| 190 | +const allCodePoints = []; |
| 191 | +for (var i = 0; i < 65536; i++) allCodePoints[i] = i; |
| 192 | +const allCharsString = String.fromCharCode.apply(String, allCodePoints); |
| 193 | +const allCharsBufferUtf8 = new Buffer(allCharsString); |
| 194 | +const allCharsBufferUcs2 = new Buffer(allCharsString, 'ucs2'); |
| 195 | + |
| 196 | +// Search for string long enough to trigger complex search with ASCII pattern |
| 197 | +// and UC16 subject. |
| 198 | +assert(!allCharsBufferUtf8.includes('notfound')); |
| 199 | +assert(!allCharsBufferUcs2.includes('notfound')); |
| 200 | + |
| 201 | +// Find substrings in Utf8. |
| 202 | +var lengths = [1, 3, 15]; // Single char, simple and complex. |
| 203 | +var indices = [0x5, 0x60, 0x400, 0x680, 0x7ee, 0xFF02, 0x16610, 0x2f77b]; |
| 204 | +for (var lengthIndex = 0; lengthIndex < lengths.length; lengthIndex++) { |
| 205 | + for (var i = 0; i < indices.length; i++) { |
| 206 | + const index = indices[i]; |
| 207 | + var length = lengths[lengthIndex]; |
| 208 | + |
| 209 | + if (index + length > 0x7F) { |
| 210 | + length = 2 * length; |
| 211 | + } |
| 212 | + |
| 213 | + if (index + length > 0x7FF) { |
| 214 | + length = 3 * length; |
| 215 | + } |
| 216 | + |
| 217 | + if (index + length > 0xFFFF) { |
| 218 | + length = 4 * length; |
| 219 | + } |
| 220 | + |
| 221 | + const patternBufferUtf8 = allCharsBufferUtf8.slice(index, index + length); |
| 222 | + assert(index, allCharsBufferUtf8.includes(patternBufferUtf8)); |
| 223 | + |
| 224 | + const patternStringUtf8 = patternBufferUtf8.toString(); |
| 225 | + assert(index, allCharsBufferUtf8.includes(patternStringUtf8)); |
| 226 | + } |
| 227 | +} |
| 228 | + |
| 229 | +// Find substrings in Usc2. |
| 230 | +lengths = [2, 4, 16]; // Single char, simple and complex. |
| 231 | +indices = [0x5, 0x65, 0x105, 0x205, 0x285, 0x2005, 0x2085, 0xfff0]; |
| 232 | +for (var lengthIndex = 0; lengthIndex < lengths.length; lengthIndex++) { |
| 233 | + for (var i = 0; i < indices.length; i++) { |
| 234 | + const index = indices[i] * 2; |
| 235 | + var length = lengths[lengthIndex]; |
| 236 | + |
| 237 | + const patternBufferUcs2 = |
| 238 | + allCharsBufferUcs2.slice(index, index + length); |
| 239 | + assert( |
| 240 | + index, allCharsBufferUcs2.includes(patternBufferUcs2, 0, 'ucs2')); |
| 241 | + |
| 242 | + const patternStringUcs2 = patternBufferUcs2.toString('ucs2'); |
| 243 | + assert( |
| 244 | + index, allCharsBufferUcs2.includes(patternStringUcs2, 0, 'ucs2')); |
| 245 | + } |
| 246 | +} |
| 247 | + |
| 248 | +assert.throws(function() { |
| 249 | + b.includes(function() { }); |
| 250 | +}); |
| 251 | +assert.throws(function() { |
| 252 | + b.includes({}); |
| 253 | +}); |
| 254 | +assert.throws(function() { |
| 255 | + b.includes([]); |
| 256 | +}); |
0 commit comments