1/* eslint-disable node/no-deprecated-api */ 2 3'use strict' 4 5var test = require('tape') 6 7var buffer = require('buffer') 8 9var index = require('./') 10var safer = require('./safer') 11var dangerous = require('./dangerous') 12 13/* Inheritance tests */ 14 15test('Default is Safer', function (t) { 16 t.equal(index, safer) 17 t.notEqual(safer, dangerous) 18 t.notEqual(index, dangerous) 19 t.end() 20}) 21 22test('Is not a function', function (t) { 23 [index, safer, dangerous].forEach(function (impl) { 24 t.equal(typeof impl, 'object') 25 t.equal(typeof impl.Buffer, 'object') 26 }); 27 [buffer].forEach(function (impl) { 28 t.equal(typeof impl, 'object') 29 t.equal(typeof impl.Buffer, 'function') 30 }) 31 t.end() 32}) 33 34test('Constructor throws', function (t) { 35 [index, safer, dangerous].forEach(function (impl) { 36 t.throws(function () { impl.Buffer() }) 37 t.throws(function () { impl.Buffer(0) }) 38 t.throws(function () { impl.Buffer('a') }) 39 t.throws(function () { impl.Buffer('a', 'utf-8') }) 40 t.throws(function () { return new impl.Buffer() }) 41 t.throws(function () { return new impl.Buffer(0) }) 42 t.throws(function () { return new impl.Buffer('a') }) 43 t.throws(function () { return new impl.Buffer('a', 'utf-8') }) 44 }) 45 t.end() 46}) 47 48test('Safe methods exist', function (t) { 49 [index, safer, dangerous].forEach(function (impl) { 50 t.equal(typeof impl.Buffer.alloc, 'function', 'alloc') 51 t.equal(typeof impl.Buffer.from, 'function', 'from') 52 }) 53 t.end() 54}) 55 56test('Unsafe methods exist only in Dangerous', function (t) { 57 [index, safer].forEach(function (impl) { 58 t.equal(typeof impl.Buffer.allocUnsafe, 'undefined') 59 t.equal(typeof impl.Buffer.allocUnsafeSlow, 'undefined') 60 }); 61 [dangerous].forEach(function (impl) { 62 t.equal(typeof impl.Buffer.allocUnsafe, 'function') 63 t.equal(typeof impl.Buffer.allocUnsafeSlow, 'function') 64 }) 65 t.end() 66}) 67 68test('Generic methods/properties are defined and equal', function (t) { 69 ['poolSize', 'isBuffer', 'concat', 'byteLength'].forEach(function (method) { 70 [index, safer, dangerous].forEach(function (impl) { 71 t.equal(impl.Buffer[method], buffer.Buffer[method], method) 72 t.notEqual(typeof impl.Buffer[method], 'undefined', method) 73 }) 74 }) 75 t.end() 76}) 77 78test('Built-in buffer static methods/properties are inherited', function (t) { 79 Object.keys(buffer).forEach(function (method) { 80 if (method === 'SlowBuffer' || method === 'Buffer') return; 81 [index, safer, dangerous].forEach(function (impl) { 82 t.equal(impl[method], buffer[method], method) 83 t.notEqual(typeof impl[method], 'undefined', method) 84 }) 85 }) 86 t.end() 87}) 88 89test('Built-in Buffer static methods/properties are inherited', function (t) { 90 Object.keys(buffer.Buffer).forEach(function (method) { 91 if (method === 'allocUnsafe' || method === 'allocUnsafeSlow') return; 92 [index, safer, dangerous].forEach(function (impl) { 93 t.equal(impl.Buffer[method], buffer.Buffer[method], method) 94 t.notEqual(typeof impl.Buffer[method], 'undefined', method) 95 }) 96 }) 97 t.end() 98}) 99 100test('.prototype property of Buffer is inherited', function (t) { 101 [index, safer, dangerous].forEach(function (impl) { 102 t.equal(impl.Buffer.prototype, buffer.Buffer.prototype, 'prototype') 103 t.notEqual(typeof impl.Buffer.prototype, 'undefined', 'prototype') 104 }) 105 t.end() 106}) 107 108test('All Safer methods are present in Dangerous', function (t) { 109 Object.keys(safer).forEach(function (method) { 110 if (method === 'Buffer') return; 111 [index, safer, dangerous].forEach(function (impl) { 112 t.equal(impl[method], safer[method], method) 113 if (method !== 'kStringMaxLength') { 114 t.notEqual(typeof impl[method], 'undefined', method) 115 } 116 }) 117 }) 118 Object.keys(safer.Buffer).forEach(function (method) { 119 [index, safer, dangerous].forEach(function (impl) { 120 t.equal(impl.Buffer[method], safer.Buffer[method], method) 121 t.notEqual(typeof impl.Buffer[method], 'undefined', method) 122 }) 123 }) 124 t.end() 125}) 126 127test('Safe methods from Dangerous methods are present in Safer', function (t) { 128 Object.keys(dangerous).forEach(function (method) { 129 if (method === 'Buffer') return; 130 [index, safer, dangerous].forEach(function (impl) { 131 t.equal(impl[method], dangerous[method], method) 132 if (method !== 'kStringMaxLength') { 133 t.notEqual(typeof impl[method], 'undefined', method) 134 } 135 }) 136 }) 137 Object.keys(dangerous.Buffer).forEach(function (method) { 138 if (method === 'allocUnsafe' || method === 'allocUnsafeSlow') return; 139 [index, safer, dangerous].forEach(function (impl) { 140 t.equal(impl.Buffer[method], dangerous.Buffer[method], method) 141 t.notEqual(typeof impl.Buffer[method], 'undefined', method) 142 }) 143 }) 144 t.end() 145}) 146 147/* Behaviour tests */ 148 149test('Methods return Buffers', function (t) { 150 [index, safer, dangerous].forEach(function (impl) { 151 t.ok(buffer.Buffer.isBuffer(impl.Buffer.alloc(0))) 152 t.ok(buffer.Buffer.isBuffer(impl.Buffer.alloc(0, 10))) 153 t.ok(buffer.Buffer.isBuffer(impl.Buffer.alloc(0, 'a'))) 154 t.ok(buffer.Buffer.isBuffer(impl.Buffer.alloc(10))) 155 t.ok(buffer.Buffer.isBuffer(impl.Buffer.alloc(10, 'x'))) 156 t.ok(buffer.Buffer.isBuffer(impl.Buffer.alloc(9, 'ab'))) 157 t.ok(buffer.Buffer.isBuffer(impl.Buffer.from(''))) 158 t.ok(buffer.Buffer.isBuffer(impl.Buffer.from('string'))) 159 t.ok(buffer.Buffer.isBuffer(impl.Buffer.from('string', 'utf-8'))) 160 t.ok(buffer.Buffer.isBuffer(impl.Buffer.from('b25ldHdvdGhyZWU=', 'base64'))) 161 t.ok(buffer.Buffer.isBuffer(impl.Buffer.from([0, 42, 3]))) 162 t.ok(buffer.Buffer.isBuffer(impl.Buffer.from(new Uint8Array([0, 42, 3])))) 163 t.ok(buffer.Buffer.isBuffer(impl.Buffer.from([]))) 164 }); 165 ['allocUnsafe', 'allocUnsafeSlow'].forEach(function (method) { 166 t.ok(buffer.Buffer.isBuffer(dangerous.Buffer[method](0))) 167 t.ok(buffer.Buffer.isBuffer(dangerous.Buffer[method](10))) 168 }) 169 t.end() 170}) 171 172test('Constructor is buffer.Buffer', function (t) { 173 [index, safer, dangerous].forEach(function (impl) { 174 t.equal(impl.Buffer.alloc(0).constructor, buffer.Buffer) 175 t.equal(impl.Buffer.alloc(0, 10).constructor, buffer.Buffer) 176 t.equal(impl.Buffer.alloc(0, 'a').constructor, buffer.Buffer) 177 t.equal(impl.Buffer.alloc(10).constructor, buffer.Buffer) 178 t.equal(impl.Buffer.alloc(10, 'x').constructor, buffer.Buffer) 179 t.equal(impl.Buffer.alloc(9, 'ab').constructor, buffer.Buffer) 180 t.equal(impl.Buffer.from('').constructor, buffer.Buffer) 181 t.equal(impl.Buffer.from('string').constructor, buffer.Buffer) 182 t.equal(impl.Buffer.from('string', 'utf-8').constructor, buffer.Buffer) 183 t.equal(impl.Buffer.from('b25ldHdvdGhyZWU=', 'base64').constructor, buffer.Buffer) 184 t.equal(impl.Buffer.from([0, 42, 3]).constructor, buffer.Buffer) 185 t.equal(impl.Buffer.from(new Uint8Array([0, 42, 3])).constructor, buffer.Buffer) 186 t.equal(impl.Buffer.from([]).constructor, buffer.Buffer) 187 }); 188 [0, 10, 100].forEach(function (arg) { 189 t.equal(dangerous.Buffer.allocUnsafe(arg).constructor, buffer.Buffer) 190 t.equal(dangerous.Buffer.allocUnsafeSlow(arg).constructor, buffer.SlowBuffer(0).constructor) 191 }) 192 t.end() 193}) 194 195test('Invalid calls throw', function (t) { 196 [index, safer, dangerous].forEach(function (impl) { 197 t.throws(function () { impl.Buffer.from(0) }) 198 t.throws(function () { impl.Buffer.from(10) }) 199 t.throws(function () { impl.Buffer.from(10, 'utf-8') }) 200 t.throws(function () { impl.Buffer.from('string', 'invalid encoding') }) 201 t.throws(function () { impl.Buffer.from(-10) }) 202 t.throws(function () { impl.Buffer.from(1e90) }) 203 t.throws(function () { impl.Buffer.from(Infinity) }) 204 t.throws(function () { impl.Buffer.from(-Infinity) }) 205 t.throws(function () { impl.Buffer.from(NaN) }) 206 t.throws(function () { impl.Buffer.from(null) }) 207 t.throws(function () { impl.Buffer.from(undefined) }) 208 t.throws(function () { impl.Buffer.from() }) 209 t.throws(function () { impl.Buffer.from({}) }) 210 t.throws(function () { impl.Buffer.alloc('') }) 211 t.throws(function () { impl.Buffer.alloc('string') }) 212 t.throws(function () { impl.Buffer.alloc('string', 'utf-8') }) 213 t.throws(function () { impl.Buffer.alloc('b25ldHdvdGhyZWU=', 'base64') }) 214 t.throws(function () { impl.Buffer.alloc(-10) }) 215 t.throws(function () { impl.Buffer.alloc(1e90) }) 216 t.throws(function () { impl.Buffer.alloc(2 * (1 << 30)) }) 217 t.throws(function () { impl.Buffer.alloc(Infinity) }) 218 t.throws(function () { impl.Buffer.alloc(-Infinity) }) 219 t.throws(function () { impl.Buffer.alloc(null) }) 220 t.throws(function () { impl.Buffer.alloc(undefined) }) 221 t.throws(function () { impl.Buffer.alloc() }) 222 t.throws(function () { impl.Buffer.alloc([]) }) 223 t.throws(function () { impl.Buffer.alloc([0, 42, 3]) }) 224 t.throws(function () { impl.Buffer.alloc({}) }) 225 }); 226 ['allocUnsafe', 'allocUnsafeSlow'].forEach(function (method) { 227 t.throws(function () { dangerous.Buffer[method]('') }) 228 t.throws(function () { dangerous.Buffer[method]('string') }) 229 t.throws(function () { dangerous.Buffer[method]('string', 'utf-8') }) 230 t.throws(function () { dangerous.Buffer[method](2 * (1 << 30)) }) 231 t.throws(function () { dangerous.Buffer[method](Infinity) }) 232 if (dangerous.Buffer[method] === buffer.Buffer.allocUnsafe) { 233 t.skip('Skipping, older impl of allocUnsafe coerced negative sizes to 0') 234 } else { 235 t.throws(function () { dangerous.Buffer[method](-10) }) 236 t.throws(function () { dangerous.Buffer[method](-1e90) }) 237 t.throws(function () { dangerous.Buffer[method](-Infinity) }) 238 } 239 t.throws(function () { dangerous.Buffer[method](null) }) 240 t.throws(function () { dangerous.Buffer[method](undefined) }) 241 t.throws(function () { dangerous.Buffer[method]() }) 242 t.throws(function () { dangerous.Buffer[method]([]) }) 243 t.throws(function () { dangerous.Buffer[method]([0, 42, 3]) }) 244 t.throws(function () { dangerous.Buffer[method]({}) }) 245 }) 246 t.end() 247}) 248 249test('Buffers have appropriate lengths', function (t) { 250 [index, safer, dangerous].forEach(function (impl) { 251 t.equal(impl.Buffer.alloc(0).length, 0) 252 t.equal(impl.Buffer.alloc(10).length, 10) 253 t.equal(impl.Buffer.from('').length, 0) 254 t.equal(impl.Buffer.from('string').length, 6) 255 t.equal(impl.Buffer.from('string', 'utf-8').length, 6) 256 t.equal(impl.Buffer.from('b25ldHdvdGhyZWU=', 'base64').length, 11) 257 t.equal(impl.Buffer.from([0, 42, 3]).length, 3) 258 t.equal(impl.Buffer.from(new Uint8Array([0, 42, 3])).length, 3) 259 t.equal(impl.Buffer.from([]).length, 0) 260 }); 261 ['allocUnsafe', 'allocUnsafeSlow'].forEach(function (method) { 262 t.equal(dangerous.Buffer[method](0).length, 0) 263 t.equal(dangerous.Buffer[method](10).length, 10) 264 }) 265 t.end() 266}) 267 268test('Buffers have appropriate lengths (2)', function (t) { 269 t.equal(index.Buffer.alloc, safer.Buffer.alloc) 270 t.equal(index.Buffer.alloc, dangerous.Buffer.alloc) 271 var ok = true; 272 [ safer.Buffer.alloc, 273 dangerous.Buffer.allocUnsafe, 274 dangerous.Buffer.allocUnsafeSlow 275 ].forEach(function (method) { 276 for (var i = 0; i < 1e2; i++) { 277 var length = Math.round(Math.random() * 1e5) 278 var buf = method(length) 279 if (!buffer.Buffer.isBuffer(buf)) ok = false 280 if (buf.length !== length) ok = false 281 } 282 }) 283 t.ok(ok) 284 t.end() 285}) 286 287test('.alloc(size) is zero-filled and has correct length', function (t) { 288 t.equal(index.Buffer.alloc, safer.Buffer.alloc) 289 t.equal(index.Buffer.alloc, dangerous.Buffer.alloc) 290 var ok = true 291 for (var i = 0; i < 1e2; i++) { 292 var length = Math.round(Math.random() * 2e6) 293 var buf = index.Buffer.alloc(length) 294 if (!buffer.Buffer.isBuffer(buf)) ok = false 295 if (buf.length !== length) ok = false 296 var j 297 for (j = 0; j < length; j++) { 298 if (buf[j] !== 0) ok = false 299 } 300 buf.fill(1) 301 for (j = 0; j < length; j++) { 302 if (buf[j] !== 1) ok = false 303 } 304 } 305 t.ok(ok) 306 t.end() 307}) 308 309test('.allocUnsafe / .allocUnsafeSlow are fillable and have correct lengths', function (t) { 310 ['allocUnsafe', 'allocUnsafeSlow'].forEach(function (method) { 311 var ok = true 312 for (var i = 0; i < 1e2; i++) { 313 var length = Math.round(Math.random() * 2e6) 314 var buf = dangerous.Buffer[method](length) 315 if (!buffer.Buffer.isBuffer(buf)) ok = false 316 if (buf.length !== length) ok = false 317 buf.fill(0, 0, length) 318 var j 319 for (j = 0; j < length; j++) { 320 if (buf[j] !== 0) ok = false 321 } 322 buf.fill(1, 0, length) 323 for (j = 0; j < length; j++) { 324 if (buf[j] !== 1) ok = false 325 } 326 } 327 t.ok(ok, method) 328 }) 329 t.end() 330}) 331 332test('.alloc(size, fill) is `fill`-filled', function (t) { 333 t.equal(index.Buffer.alloc, safer.Buffer.alloc) 334 t.equal(index.Buffer.alloc, dangerous.Buffer.alloc) 335 var ok = true 336 for (var i = 0; i < 1e2; i++) { 337 var length = Math.round(Math.random() * 2e6) 338 var fill = Math.round(Math.random() * 255) 339 var buf = index.Buffer.alloc(length, fill) 340 if (!buffer.Buffer.isBuffer(buf)) ok = false 341 if (buf.length !== length) ok = false 342 for (var j = 0; j < length; j++) { 343 if (buf[j] !== fill) ok = false 344 } 345 } 346 t.ok(ok) 347 t.end() 348}) 349 350test('.alloc(size, fill) is `fill`-filled', function (t) { 351 t.equal(index.Buffer.alloc, safer.Buffer.alloc) 352 t.equal(index.Buffer.alloc, dangerous.Buffer.alloc) 353 var ok = true 354 for (var i = 0; i < 1e2; i++) { 355 var length = Math.round(Math.random() * 2e6) 356 var fill = Math.round(Math.random() * 255) 357 var buf = index.Buffer.alloc(length, fill) 358 if (!buffer.Buffer.isBuffer(buf)) ok = false 359 if (buf.length !== length) ok = false 360 for (var j = 0; j < length; j++) { 361 if (buf[j] !== fill) ok = false 362 } 363 } 364 t.ok(ok) 365 t.deepEqual(index.Buffer.alloc(9, 'a'), index.Buffer.alloc(9, 97)) 366 t.notDeepEqual(index.Buffer.alloc(9, 'a'), index.Buffer.alloc(9, 98)) 367 368 var tmp = new buffer.Buffer(2) 369 tmp.fill('ok') 370 if (tmp[1] === tmp[0]) { 371 // Outdated Node.js 372 t.deepEqual(index.Buffer.alloc(5, 'ok'), index.Buffer.from('ooooo')) 373 } else { 374 t.deepEqual(index.Buffer.alloc(5, 'ok'), index.Buffer.from('okoko')) 375 } 376 t.notDeepEqual(index.Buffer.alloc(5, 'ok'), index.Buffer.from('kokok')) 377 378 t.end() 379}) 380 381test('safer.Buffer.from returns results same as Buffer constructor', function (t) { 382 [index, safer, dangerous].forEach(function (impl) { 383 t.deepEqual(impl.Buffer.from(''), new buffer.Buffer('')) 384 t.deepEqual(impl.Buffer.from('string'), new buffer.Buffer('string')) 385 t.deepEqual(impl.Buffer.from('string', 'utf-8'), new buffer.Buffer('string', 'utf-8')) 386 t.deepEqual(impl.Buffer.from('b25ldHdvdGhyZWU=', 'base64'), new buffer.Buffer('b25ldHdvdGhyZWU=', 'base64')) 387 t.deepEqual(impl.Buffer.from([0, 42, 3]), new buffer.Buffer([0, 42, 3])) 388 t.deepEqual(impl.Buffer.from(new Uint8Array([0, 42, 3])), new buffer.Buffer(new Uint8Array([0, 42, 3]))) 389 t.deepEqual(impl.Buffer.from([]), new buffer.Buffer([])) 390 }) 391 t.end() 392}) 393 394test('safer.Buffer.from returns consistent results', function (t) { 395 [index, safer, dangerous].forEach(function (impl) { 396 t.deepEqual(impl.Buffer.from(''), impl.Buffer.alloc(0)) 397 t.deepEqual(impl.Buffer.from([]), impl.Buffer.alloc(0)) 398 t.deepEqual(impl.Buffer.from(new Uint8Array([])), impl.Buffer.alloc(0)) 399 t.deepEqual(impl.Buffer.from('string', 'utf-8'), impl.Buffer.from('string')) 400 t.deepEqual(impl.Buffer.from('string'), impl.Buffer.from([115, 116, 114, 105, 110, 103])) 401 t.deepEqual(impl.Buffer.from('string'), impl.Buffer.from(impl.Buffer.from('string'))) 402 t.deepEqual(impl.Buffer.from('b25ldHdvdGhyZWU=', 'base64'), impl.Buffer.from('onetwothree')) 403 t.notDeepEqual(impl.Buffer.from('b25ldHdvdGhyZWU='), impl.Buffer.from('onetwothree')) 404 }) 405 t.end() 406}) 407