• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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