Merge branch 'v0.10'
[platform/upstream/nodejs.git] / test / simple / test-buffer.js
1 // Copyright Joyent, Inc. and other Node contributors.
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to permit
8 // persons to whom the Software is furnished to do so, subject to the
9 // following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 // USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22 var common = require('../common');
23 var assert = require('assert');
24
25 var SlowBuffer = require('buffer').SlowBuffer;
26 var Buffer = require('buffer').Buffer;
27
28 // counter to ensure unique value is always copied
29 var cntr = 0;
30
31 // Regression test for segfault introduced in commit e501ce4.
32 ['base64','binary','ucs2','utf8','ascii'].forEach(function(encoding) {
33   var buf = new SlowBuffer(0);
34   buf.write('', encoding);
35 });
36
37 var b = Buffer(1024); // safe constructor
38
39 console.log('b.length == %d', b.length);
40 assert.strictEqual(1024, b.length);
41
42 b[0] = -1;
43 assert.strictEqual(b[0], 255);
44
45 for (var i = 0; i < 1024; i++) {
46   b[i] = i % 256;
47 }
48
49 for (var i = 0; i < 1024; i++) {
50   assert.strictEqual(i % 256, b[i]);
51 }
52
53 var c = new Buffer(512);
54 console.log('c.length == %d', c.length);
55 assert.strictEqual(512, c.length);
56
57 // copy 512 bytes, from 0 to 512.
58 b.fill(++cntr);
59 c.fill(++cntr);
60 var copied = b.copy(c, 0, 0, 512);
61 console.log('copied %d bytes from b into c', copied);
62 assert.strictEqual(512, copied);
63 for (var i = 0; i < c.length; i++) {
64   assert.strictEqual(b[i], c[i]);
65 }
66
67 // copy c into b, without specifying sourceEnd
68 b.fill(++cntr);
69 c.fill(++cntr);
70 var copied = c.copy(b, 0, 0);
71 console.log('copied %d bytes from c into b w/o sourceEnd', copied);
72 assert.strictEqual(c.length, copied);
73 for (var i = 0; i < c.length; i++) {
74   assert.strictEqual(c[i], b[i]);
75 }
76
77 // copy c into b, without specifying sourceStart
78 b.fill(++cntr);
79 c.fill(++cntr);
80 var copied = c.copy(b, 0);
81 console.log('copied %d bytes from c into b w/o sourceStart', copied);
82 assert.strictEqual(c.length, copied);
83 for (var i = 0; i < c.length; i++) {
84   assert.strictEqual(c[i], b[i]);
85 }
86
87 // copy longer buffer b to shorter c without targetStart
88 b.fill(++cntr);
89 c.fill(++cntr);
90 var copied = b.copy(c);
91 console.log('copied %d bytes from b into c w/o targetStart', copied);
92 assert.strictEqual(c.length, copied);
93 for (var i = 0; i < c.length; i++) {
94   assert.strictEqual(b[i], c[i]);
95 }
96
97 // copy starting near end of b to c
98 b.fill(++cntr);
99 c.fill(++cntr);
100 var copied = b.copy(c, 0, b.length - Math.floor(c.length / 2));
101 console.log('copied %d bytes from end of b into beginning of c', copied);
102 assert.strictEqual(Math.floor(c.length / 2), copied);
103 for (var i = 0; i < Math.floor(c.length / 2); i++) {
104   assert.strictEqual(b[b.length - Math.floor(c.length / 2) + i], c[i]);
105 }
106 for (var i = Math.floor(c.length /2) + 1; i < c.length; i++) {
107   assert.strictEqual(c[c.length-1], c[i]);
108 }
109
110 // try to copy 513 bytes, and check we don't overrun c
111 b.fill(++cntr);
112 c.fill(++cntr);
113 var copied = b.copy(c, 0, 0, 513);
114 console.log('copied %d bytes from b trying to overrun c', copied);
115 assert.strictEqual(c.length, copied);
116 for (var i = 0; i < c.length; i++) {
117   assert.strictEqual(b[i], c[i]);
118 }
119
120 // copy 768 bytes from b into b
121 b.fill(++cntr);
122 b.fill(++cntr, 256);
123 var copied = b.copy(b, 0, 256, 1024);
124 console.log('copied %d bytes from b into b', copied);
125 assert.strictEqual(768, copied);
126 for (var i = 0; i < b.length; i++) {
127   assert.strictEqual(cntr, b[i]);
128 }
129
130
131 // copy from fast to slow buffer
132 var sb = new SlowBuffer(b.length);
133 var copied = b.copy(sb);
134 console.log('copied %d bytes from b into sb');
135 for (var i = 0; i < sb.length; i++) {
136   assert.strictEqual(sb[i], b[i]);
137 }
138
139 var caught_error = null;
140
141 // try to copy from before the beginning of b
142 caught_error = null;
143 try {
144   var copied = b.copy(c, 0, 100, 10);
145 } catch (err) {
146   caught_error = err;
147 }
148
149 // copy from b to c with negative sourceStart
150 b.fill(++cntr);
151 c.fill(++cntr);
152 var copied = b.copy(c, 0, -1);
153 assert.strictEqual(c.length, copied);
154 console.log('copied %d bytes from b into c w/ negative sourceStart', copied);
155 for (var i = 0; i < c.length; i++) {
156   assert.strictEqual(b[i], c[i]);
157 }
158
159 // check sourceEnd resets to targetEnd if former is greater than the latter
160 b.fill(++cntr);
161 c.fill(++cntr);
162 var copied = b.copy(c, 0, 0, 1025);
163 console.log('copied %d bytes from b into c', copied);
164 for (var i = 0; i < c.length; i++) {
165   assert.strictEqual(b[i], c[i]);
166 }
167
168 // copy from fast buffer to slow buffer without parameters
169 var sb = new SlowBuffer(b.length);
170 sb.fill(++cntr, 0, sb.length);
171 b.fill(++cntr);
172 var copied = b.copy(sb);
173 console.log('copied %d bytes from fast buffer to slow buffer', copied);
174 for (var i = 0 ; i < b.length; i++) {
175   assert.strictEqual(b[i], sb[i]);
176 }
177
178 // throw with negative sourceEnd
179 console.log('test copy at negative sourceEnd');
180 assert.throws(function() {
181   b.copy(c, 0, 0, -1);
182 }, RangeError);
183
184 // throw when sourceStart is greater than sourceEnd
185 assert.throws(function() {
186   b.copy(c, 0, 100, 10);
187 }, RangeError);
188
189 // throw attempting to copy after end of c
190 assert.throws(function() {
191   b.copy(c, 512, 0, 10);
192 }, RangeError);
193
194 var caught_error;
195
196 // invalid encoding for Buffer.toString
197 caught_error = null;
198 try {
199   var copied = b.toString('invalid');
200 } catch (err) {
201   caught_error = err;
202 }
203 assert.strictEqual('Unknown encoding: invalid', caught_error.message);
204
205 // invalid encoding for Buffer.write
206 caught_error = null;
207 try {
208   var copied = b.write('test string', 0, 5, 'invalid');
209 } catch (err) {
210   caught_error = err;
211 }
212 assert.strictEqual('Unknown encoding: invalid', caught_error.message);
213
214 // try to create 0-length buffers
215 new Buffer('');
216 new Buffer('', 'ascii');
217 new Buffer('', 'binary');
218 new Buffer(0);
219
220 // try to write a 0-length string beyond the end of b
221 b.write('', 1024);
222 b.write('', 2048);
223
224 // try to copy 0 bytes worth of data into an empty buffer
225 b.copy(new Buffer(0), 0, 0, 0);
226
227 // try to copy 0 bytes past the end of the target buffer
228 b.copy(new Buffer(0), 1, 1, 1);
229 b.copy(new Buffer(1), 1, 1, 1);
230
231 // try to copy 0 bytes from past the end of the source buffer
232 b.copy(new Buffer(1), 0, 2048, 2048);
233
234 // try to toString() a 0-length slice of a buffer, both within and without the
235 // valid buffer range
236 assert.equal(new Buffer('abc').toString('ascii', 0, 0), '');
237 assert.equal(new Buffer('abc').toString('ascii', -100, -100), '');
238 assert.equal(new Buffer('abc').toString('ascii', 100, 100), '');
239
240 // try toString() with a object as a encoding
241 assert.equal(new Buffer('abc').toString({toString: function() {
242   return 'ascii';
243 }}), 'abc');
244
245 // testing for smart defaults and ability to pass string values as offset
246 var writeTest = new Buffer('abcdes');
247 writeTest.write('n', 'ascii');
248 writeTest.write('o', 'ascii', '1');
249 writeTest.write('d', '2', 'ascii');
250 writeTest.write('e', 3, 'ascii');
251 writeTest.write('j', 'ascii', 4);
252 assert.equal(writeTest.toString(), 'nodejs');
253
254 var asciiString = 'hello world';
255 var offset = 100;
256 for (var j = 0; j < 500; j++) {
257
258   for (var i = 0; i < asciiString.length; i++) {
259     b[i] = asciiString.charCodeAt(i);
260   }
261   var asciiSlice = b.toString('ascii', 0, asciiString.length);
262   assert.equal(asciiString, asciiSlice);
263
264   var written = b.write(asciiString, offset, 'ascii');
265   assert.equal(asciiString.length, written);
266   var asciiSlice = b.toString('ascii', offset, offset + asciiString.length);
267   assert.equal(asciiString, asciiSlice);
268
269   var sliceA = b.slice(offset, offset + asciiString.length);
270   var sliceB = b.slice(offset, offset + asciiString.length);
271   for (var i = 0; i < asciiString.length; i++) {
272     assert.equal(sliceA[i], sliceB[i]);
273   }
274
275   // TODO utf8 slice tests
276 }
277
278
279 for (var j = 0; j < 100; j++) {
280   var slice = b.slice(100, 150);
281   assert.equal(50, slice.length);
282   for (var i = 0; i < 50; i++) {
283     assert.equal(b[100 + i], slice[i]);
284   }
285 }
286
287
288
289 // Bug regression test
290 var testValue = '\u00F6\u65E5\u672C\u8A9E'; // ö日本語
291 var buffer = new Buffer(32);
292 var size = buffer.write(testValue, 0, 'utf8');
293 console.log('bytes written to buffer: ' + size);
294 var slice = buffer.toString('utf8', 0, size);
295 assert.equal(slice, testValue);
296
297
298 // Test triple  slice
299 var a = new Buffer(8);
300 for (var i = 0; i < 8; i++) a[i] = i;
301 var b = a.slice(4, 8);
302 assert.equal(4, b[0]);
303 assert.equal(5, b[1]);
304 assert.equal(6, b[2]);
305 assert.equal(7, b[3]);
306 var c = b.slice(2, 4);
307 assert.equal(6, c[0]);
308 assert.equal(7, c[1]);
309
310
311 var d = new Buffer([23, 42, 255]);
312 assert.equal(d.length, 3);
313 assert.equal(d[0], 23);
314 assert.equal(d[1], 42);
315 assert.equal(d[2], 255);
316 assert.deepEqual(d, new Buffer(d));
317
318 var e = new Buffer('über');
319 console.error('uber: \'%s\'', e.toString());
320 assert.deepEqual(e, new Buffer([195, 188, 98, 101, 114]));
321
322 var f = new Buffer('über', 'ascii');
323 console.error('f.length: %d     (should be 4)', f.length);
324 assert.deepEqual(f, new Buffer([252, 98, 101, 114]));
325
326 ['ucs2', 'ucs-2', 'utf16le', 'utf-16le'].forEach(function(encoding) {
327   var f = new Buffer('über', encoding);
328   console.error('f.length: %d     (should be 8)', f.length);
329   assert.deepEqual(f, new Buffer([252, 0, 98, 0, 101, 0, 114, 0]));
330
331   var f = new Buffer('привет', encoding);
332   console.error('f.length: %d     (should be 12)', f.length);
333   assert.deepEqual(f, new Buffer([63, 4, 64, 4, 56, 4, 50, 4, 53, 4, 66, 4]));
334   assert.equal(f.toString(encoding), 'привет');
335
336   var f = new Buffer([0, 0, 0, 0, 0]);
337   assert.equal(f.length, 5);
338   var size = f.write('あいうえお', encoding);
339   console.error('bytes written to buffer: %d     (should be 4)', size);
340   assert.equal(size, 4);
341   assert.deepEqual(f, new Buffer([0x42, 0x30, 0x44, 0x30, 0x00]));
342 });
343
344 var f = new Buffer('\uD83D\uDC4D', 'utf-16le'); // THUMBS UP SIGN (U+1F44D)
345 assert.equal(f.length, 4);
346 assert.deepEqual(f, new Buffer('3DD84DDC', 'hex'));
347
348
349 var arrayIsh = {0: 0, 1: 1, 2: 2, 3: 3, length: 4};
350 var g = new Buffer(arrayIsh);
351 assert.deepEqual(g, new Buffer([0, 1, 2, 3]));
352 var strArrayIsh = {0: '0', 1: '1', 2: '2', 3: '3', length: 4};
353 g = new Buffer(strArrayIsh);
354 assert.deepEqual(g, new Buffer([0, 1, 2, 3]));
355
356
357 //
358 // Test toString('base64')
359 //
360 assert.equal('TWFu', (new Buffer('Man')).toString('base64'));
361
362 // test that regular and URL-safe base64 both work
363 var expected = [0xff, 0xff, 0xbe, 0xff, 0xef, 0xbf, 0xfb, 0xef, 0xff];
364 assert.deepEqual(Buffer('//++/++/++//', 'base64'), Buffer(expected));
365 assert.deepEqual(Buffer('__--_--_--__', 'base64'), Buffer(expected));
366
367 // big example
368 var quote = 'Man is distinguished, not only by his reason, but by this ' +
369             'singular passion from other animals, which is a lust ' +
370             'of the mind, that by a perseverance of delight in the continued ' +
371             'and indefatigable generation of knowledge, exceeds the short ' +
372             'vehemence of any carnal pleasure.';
373 var expected = 'TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24s' +
374                'IGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltY' +
375                'WxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZX' +
376                'JzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmR' +
377                'lZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo' +
378                'ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=';
379 assert.equal(expected, (new Buffer(quote)).toString('base64'));
380
381
382 b = new Buffer(1024);
383 var bytesWritten = b.write(expected, 0, 'base64');
384 assert.equal(quote.length, bytesWritten);
385 assert.equal(quote, b.toString('ascii', 0, quote.length));
386
387 // check that the base64 decoder ignores whitespace
388 var expectedWhite = expected.slice(0, 60) + ' \n' +
389                     expected.slice(60, 120) + ' \n' +
390                     expected.slice(120, 180) + ' \n' +
391                     expected.slice(180, 240) + ' \n' +
392                     expected.slice(240, 300) + '\n' +
393                     expected.slice(300, 360) + '\n';
394 b = new Buffer(1024);
395 bytesWritten = b.write(expectedWhite, 0, 'base64');
396 assert.equal(quote.length, bytesWritten);
397 assert.equal(quote, b.toString('ascii', 0, quote.length));
398
399 // check that the base64 decoder on the constructor works
400 // even in the presence of whitespace.
401 b = new Buffer(expectedWhite, 'base64');
402 assert.equal(quote.length, b.length);
403 assert.equal(quote, b.toString('ascii', 0, quote.length));
404
405 // check that the base64 decoder ignores illegal chars
406 var expectedIllegal = expected.slice(0, 60) + ' \x80' +
407                       expected.slice(60, 120) + ' \xff' +
408                       expected.slice(120, 180) + ' \x00' +
409                       expected.slice(180, 240) + ' \x98' +
410                       expected.slice(240, 300) + '\x03' +
411                       expected.slice(300, 360);
412 b = new Buffer(expectedIllegal, 'base64');
413 assert.equal(quote.length, b.length);
414 assert.equal(quote, b.toString('ascii', 0, quote.length));
415
416
417 assert.equal(new Buffer('', 'base64').toString(), '');
418 assert.equal(new Buffer('K', 'base64').toString(), '');
419
420 // multiple-of-4 with padding
421 assert.equal(new Buffer('Kg==', 'base64').toString(), '*');
422 assert.equal(new Buffer('Kio=', 'base64').toString(), '**');
423 assert.equal(new Buffer('Kioq', 'base64').toString(), '***');
424 assert.equal(new Buffer('KioqKg==', 'base64').toString(), '****');
425 assert.equal(new Buffer('KioqKio=', 'base64').toString(), '*****');
426 assert.equal(new Buffer('KioqKioq', 'base64').toString(), '******');
427 assert.equal(new Buffer('KioqKioqKg==', 'base64').toString(), '*******');
428 assert.equal(new Buffer('KioqKioqKio=', 'base64').toString(), '********');
429 assert.equal(new Buffer('KioqKioqKioq', 'base64').toString(), '*********');
430 assert.equal(new Buffer('KioqKioqKioqKg==', 'base64').toString(),
431              '**********');
432 assert.equal(new Buffer('KioqKioqKioqKio=', 'base64').toString(),
433              '***********');
434 assert.equal(new Buffer('KioqKioqKioqKioq', 'base64').toString(),
435              '************');
436 assert.equal(new Buffer('KioqKioqKioqKioqKg==', 'base64').toString(),
437              '*************');
438 assert.equal(new Buffer('KioqKioqKioqKioqKio=', 'base64').toString(),
439              '**************');
440 assert.equal(new Buffer('KioqKioqKioqKioqKioq', 'base64').toString(),
441              '***************');
442 assert.equal(new Buffer('KioqKioqKioqKioqKioqKg==', 'base64').toString(),
443              '****************');
444 assert.equal(new Buffer('KioqKioqKioqKioqKioqKio=', 'base64').toString(),
445              '*****************');
446 assert.equal(new Buffer('KioqKioqKioqKioqKioqKioq', 'base64').toString(),
447              '******************');
448 assert.equal(new Buffer('KioqKioqKioqKioqKioqKioqKg==', 'base64').toString(),
449              '*******************');
450 assert.equal(new Buffer('KioqKioqKioqKioqKioqKioqKio=', 'base64').toString(),
451              '********************');
452
453 // no padding, not a multiple of 4
454 assert.equal(new Buffer('Kg', 'base64').toString(), '*');
455 assert.equal(new Buffer('Kio', 'base64').toString(), '**');
456 assert.equal(new Buffer('KioqKg', 'base64').toString(), '****');
457 assert.equal(new Buffer('KioqKio', 'base64').toString(), '*****');
458 assert.equal(new Buffer('KioqKioqKg', 'base64').toString(), '*******');
459 assert.equal(new Buffer('KioqKioqKio', 'base64').toString(), '********');
460 assert.equal(new Buffer('KioqKioqKioqKg', 'base64').toString(), '**********');
461 assert.equal(new Buffer('KioqKioqKioqKio', 'base64').toString(), '***********');
462 assert.equal(new Buffer('KioqKioqKioqKioqKg', 'base64').toString(),
463              '*************');
464 assert.equal(new Buffer('KioqKioqKioqKioqKio', 'base64').toString(),
465              '**************');
466 assert.equal(new Buffer('KioqKioqKioqKioqKioqKg', 'base64').toString(),
467              '****************');
468 assert.equal(new Buffer('KioqKioqKioqKioqKioqKio', 'base64').toString(),
469              '*****************');
470 assert.equal(new Buffer('KioqKioqKioqKioqKioqKioqKg', 'base64').toString(),
471              '*******************');
472 assert.equal(new Buffer('KioqKioqKioqKioqKioqKioqKio', 'base64').toString(),
473              '********************');
474
475 // handle padding graciously, multiple-of-4 or not
476 assert.equal(new Buffer('72INjkR5fchcxk9+VgdGPFJDxUBFR5/rMFsghgxADiw==',
477                         'base64').length, 32);
478 assert.equal(new Buffer('72INjkR5fchcxk9+VgdGPFJDxUBFR5/rMFsghgxADiw=',
479                         'base64').length, 32);
480 assert.equal(new Buffer('72INjkR5fchcxk9+VgdGPFJDxUBFR5/rMFsghgxADiw',
481                         'base64').length, 32);
482 assert.equal(new Buffer('w69jACy6BgZmaFvv96HG6MYksWytuZu3T1FvGnulPg==',
483                         'base64').length, 31);
484 assert.equal(new Buffer('w69jACy6BgZmaFvv96HG6MYksWytuZu3T1FvGnulPg=',
485                         'base64').length, 31);
486 assert.equal(new Buffer('w69jACy6BgZmaFvv96HG6MYksWytuZu3T1FvGnulPg',
487                         'base64').length, 31);
488
489 // This string encodes single '.' character in UTF-16
490 var dot = new Buffer('//4uAA==', 'base64');
491 assert.equal(dot[0], 0xff);
492 assert.equal(dot[1], 0xfe);
493 assert.equal(dot[2], 0x2e);
494 assert.equal(dot[3], 0x00);
495 assert.equal(dot.toString('base64'), '//4uAA==');
496
497 // Writing base64 at a position > 0 should not mangle the result.
498 //
499 // https://github.com/joyent/node/issues/402
500 var segments = ['TWFkbmVzcz8h', 'IFRoaXM=', 'IGlz', 'IG5vZGUuanMh'];
501 var buf = new Buffer(64);
502 var pos = 0;
503
504 for (var i = 0; i < segments.length; ++i) {
505   pos += b.write(segments[i], pos, 'base64');
506 }
507 assert.equal(b.toString('binary', 0, pos), 'Madness?! This is node.js!');
508
509 // Creating buffers larger than pool size.
510 var l = Buffer.poolSize + 5;
511 var s = '';
512 for (i = 0; i < l; i++) {
513   s += 'h';
514 }
515
516 var b = new Buffer(s);
517
518 for (i = 0; i < l; i++) {
519   assert.equal('h'.charCodeAt(0), b[i]);
520 }
521
522 var sb = b.toString();
523 assert.equal(sb.length, s.length);
524 assert.equal(sb, s);
525
526
527 // Single argument slice
528 b = new Buffer('abcde');
529 assert.equal('bcde', b.slice(1).toString());
530
531 // byte length
532 assert.equal(14, Buffer.byteLength('Il était tué'));
533 assert.equal(14, Buffer.byteLength('Il était tué', 'utf8'));
534 ['ucs2', 'ucs-2', 'utf16le', 'utf-16le'].forEach(function(encoding) {
535   assert.equal(24, Buffer.byteLength('Il était tué', encoding));
536 });
537 assert.equal(12, Buffer.byteLength('Il était tué', 'ascii'));
538 assert.equal(12, Buffer.byteLength('Il était tué', 'binary'));
539
540 // slice(0,0).length === 0
541 assert.equal(0, Buffer('hello').slice(0, 0).length);
542
543 // test hex toString
544 console.log('Create hex string from buffer');
545 var hexb = new Buffer(256);
546 for (var i = 0; i < 256; i++) {
547   hexb[i] = i;
548 }
549 var hexStr = hexb.toString('hex');
550 assert.equal(hexStr,
551              '000102030405060708090a0b0c0d0e0f' +
552              '101112131415161718191a1b1c1d1e1f' +
553              '202122232425262728292a2b2c2d2e2f' +
554              '303132333435363738393a3b3c3d3e3f' +
555              '404142434445464748494a4b4c4d4e4f' +
556              '505152535455565758595a5b5c5d5e5f' +
557              '606162636465666768696a6b6c6d6e6f' +
558              '707172737475767778797a7b7c7d7e7f' +
559              '808182838485868788898a8b8c8d8e8f' +
560              '909192939495969798999a9b9c9d9e9f' +
561              'a0a1a2a3a4a5a6a7a8a9aaabacadaeaf' +
562              'b0b1b2b3b4b5b6b7b8b9babbbcbdbebf' +
563              'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf' +
564              'd0d1d2d3d4d5d6d7d8d9dadbdcdddedf' +
565              'e0e1e2e3e4e5e6e7e8e9eaebecedeeef' +
566              'f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff');
567
568 console.log('Create buffer from hex string');
569 var hexb2 = new Buffer(hexStr, 'hex');
570 for (var i = 0; i < 256; i++) {
571   assert.equal(hexb2[i], hexb[i]);
572 }
573
574 // test an invalid slice end.
575 console.log('Try to slice off the end of the buffer');
576 var b = new Buffer([1, 2, 3, 4, 5]);
577 var b2 = b.toString('hex', 1, 10000);
578 var b3 = b.toString('hex', 1, 5);
579 var b4 = b.toString('hex', 1);
580 assert.equal(b2, b3);
581 assert.equal(b2, b4);
582
583
584 // Test slice on SlowBuffer GH-843
585 var SlowBuffer = process.binding('buffer').SlowBuffer;
586
587 function buildSlowBuffer(data) {
588   if (Array.isArray(data)) {
589     var buffer = new SlowBuffer(data.length);
590     data.forEach(function(v, k) {
591       buffer[k] = v;
592     });
593     return buffer;
594   }
595   return null;
596 }
597
598 var x = buildSlowBuffer([0x81, 0xa3, 0x66, 0x6f, 0x6f, 0xa3, 0x62, 0x61, 0x72]);
599
600 console.log(x.inspect());
601 assert.equal('<SlowBuffer 81 a3 66 6f 6f a3 62 61 72>', x.inspect());
602
603 var z = x.slice(4);
604 console.log(z.inspect());
605 console.log(z.length);
606 assert.equal(5, z.length);
607 assert.equal(0x6f, z[0]);
608 assert.equal(0xa3, z[1]);
609 assert.equal(0x62, z[2]);
610 assert.equal(0x61, z[3]);
611 assert.equal(0x72, z[4]);
612
613 var z = x.slice(0);
614 console.log(z.inspect());
615 console.log(z.length);
616 assert.equal(z.length, x.length);
617
618 var z = x.slice(0, 4);
619 console.log(z.inspect());
620 console.log(z.length);
621 assert.equal(4, z.length);
622 assert.equal(0x81, z[0]);
623 assert.equal(0xa3, z[1]);
624
625 var z = x.slice(0, 9);
626 console.log(z.inspect());
627 console.log(z.length);
628 assert.equal(9, z.length);
629
630 var z = x.slice(1, 4);
631 console.log(z.inspect());
632 console.log(z.length);
633 assert.equal(3, z.length);
634 assert.equal(0xa3, z[0]);
635
636 var z = x.slice(2, 4);
637 console.log(z.inspect());
638 console.log(z.length);
639 assert.equal(2, z.length);
640 assert.equal(0x66, z[0]);
641 assert.equal(0x6f, z[1]);
642
643 assert.equal(0, Buffer('hello').slice(0, 0).length);
644
645 b = new Buffer(50);
646 b.fill('h');
647 for (var i = 0; i < b.length; i++) {
648   assert.equal('h'.charCodeAt(0), b[i]);
649 }
650
651 b.fill(0);
652 for (var i = 0; i < b.length; i++) {
653   assert.equal(0, b[i]);
654 }
655
656 b.fill(1, 16, 32);
657 for (var i = 0; i < 16; i++) assert.equal(0, b[i]);
658 for (; i < 32; i++) assert.equal(1, b[i]);
659 for (; i < b.length; i++) assert.equal(0, b[i]);
660
661 ['ucs2', 'ucs-2', 'utf16le', 'utf-16le'].forEach(function(encoding) {
662   var b = new SlowBuffer(10);
663   b.write('あいうえお', encoding);
664   assert.equal(b.toString(encoding), 'あいうえお');
665 });
666
667 // Binary encoding should write only one byte per character.
668 var b = Buffer([0xde, 0xad, 0xbe, 0xef]);
669 var s = String.fromCharCode(0xffff);
670 b.write(s, 0, 'binary');
671 assert.equal(0xff, b[0]);
672 assert.equal(0xad, b[1]);
673 assert.equal(0xbe, b[2]);
674 assert.equal(0xef, b[3]);
675 s = String.fromCharCode(0xaaee);
676 b.write(s, 0, 'binary');
677 assert.equal(0xee, b[0]);
678 assert.equal(0xad, b[1]);
679 assert.equal(0xbe, b[2]);
680 assert.equal(0xef, b[3]);
681
682 // testing invalid encoding on SlowBuffer.toString
683 caught_error = null;
684 try {
685   var copied = b.toString('invalid');
686 } catch (err) {
687   caught_error = err;
688 }
689 assert.strictEqual('Unknown encoding: invalid', caught_error.message);
690
691 // testing invalid encoding on SlowBuffer.write
692 caught_error = null;
693 try {
694   var copied = b.write('some string', 0, 5, 'invalid');
695 } catch (err) {
696   caught_error = err;
697 }
698 assert.strictEqual('Unknown encoding: invalid', caught_error.message);
699
700
701 // This should not segfault the program.
702 assert.throws(function() {
703   new Buffer('"pong"', 0, 6, 8031, '127.0.0.1');
704 });
705
706 // #1210 Test UTF-8 string includes null character
707 var buf = new Buffer('\0');
708 assert.equal(buf.length, 1);
709 buf = new Buffer('\0\0');
710 assert.equal(buf.length, 2);
711
712 buf = new Buffer(2);
713 var written = buf.write(''); // 0byte
714 assert.equal(written, 0);
715 written = buf.write('\0'); // 1byte (v8 adds null terminator)
716 assert.equal(written, 1);
717 written = buf.write('a\0'); // 1byte * 2
718 assert.equal(written, 2);
719 written = buf.write('あ'); // 3bytes
720 assert.equal(written, 0);
721 written = buf.write('\0あ'); // 1byte + 3bytes
722 assert.equal(written, 1);
723 written = buf.write('\0\0あ'); // 1byte * 2 + 3bytes
724 assert.equal(written, 2);
725
726 buf = new Buffer(10);
727 written = buf.write('あいう'); // 3bytes * 3 (v8 adds null terminator)
728 assert.equal(written, 9);
729 written = buf.write('あいう\0'); // 3bytes * 3 + 1byte
730 assert.equal(written, 10);
731
732 // #243 Test write() with maxLength
733 var buf = new Buffer(4);
734 buf.fill(0xFF);
735 var written = buf.write('abcd', 1, 2, 'utf8');
736 console.log(buf);
737 assert.equal(written, 2);
738 assert.equal(buf[0], 0xFF);
739 assert.equal(buf[1], 0x61);
740 assert.equal(buf[2], 0x62);
741 assert.equal(buf[3], 0xFF);
742
743 buf.fill(0xFF);
744 written = buf.write('abcd', 1, 4);
745 console.log(buf);
746 assert.equal(written, 3);
747 assert.equal(buf[0], 0xFF);
748 assert.equal(buf[1], 0x61);
749 assert.equal(buf[2], 0x62);
750 assert.equal(buf[3], 0x63);
751
752 buf.fill(0xFF);
753 written = buf.write('abcd', 'utf8', 1, 2);  // legacy style
754 console.log(buf);
755 assert.equal(written, 2);
756 assert.equal(buf[0], 0xFF);
757 assert.equal(buf[1], 0x61);
758 assert.equal(buf[2], 0x62);
759 assert.equal(buf[3], 0xFF);
760
761 buf.fill(0xFF);
762 written = buf.write('abcdef', 1, 2, 'hex');
763 console.log(buf);
764 assert.equal(written, 2);
765 assert.equal(buf[0], 0xFF);
766 assert.equal(buf[1], 0xAB);
767 assert.equal(buf[2], 0xCD);
768 assert.equal(buf[3], 0xFF);
769
770 ['ucs2', 'ucs-2', 'utf16le', 'utf-16le'].forEach(function(encoding) {
771   buf.fill(0xFF);
772   written = buf.write('abcd', 0, 2, encoding);
773   console.log(buf);
774   assert.equal(written, 2);
775   assert.equal(buf[0], 0x61);
776   assert.equal(buf[1], 0x00);
777   assert.equal(buf[2], 0xFF);
778   assert.equal(buf[3], 0xFF);
779 });
780
781 // test for buffer overrun
782 buf = new Buffer([0, 0, 0, 0, 0]); // length: 5
783 var sub = buf.slice(0, 4);         // length: 4
784 written = sub.write('12345', 'binary');
785 assert.equal(written, 4);
786 assert.equal(buf[4], 0);
787
788 // Check for fractional length args, junk length args, etc.
789 // https://github.com/joyent/node/issues/1758
790 Buffer(3.3).toString(); // throws bad argument error in commit 43cb4ec
791 assert.equal(Buffer(-1).length, 0);
792 assert.equal(Buffer(NaN).length, 0);
793 assert.equal(Buffer(3.3).length, 4);
794 assert.equal(Buffer({length: 3.3}).length, 4);
795 assert.equal(Buffer({length: 'BAM'}).length, 0);
796
797 // Make sure that strings are not coerced to numbers.
798 assert.equal(Buffer('99').length, 2);
799 assert.equal(Buffer('13.37').length, 5);
800
801 // Ensure that the length argument is respected.
802 'ascii utf8 hex base64 binary'.split(' ').forEach(function(enc) {
803   assert.equal(Buffer(1).write('aaaaaa', 0, 1, enc), 1);
804 });
805
806 // Regression test, guard against buffer overrun in the base64 decoder.
807 var a = Buffer(3);
808 var b = Buffer('xxx');
809 a.write('aaaaaaaa', 'base64');
810 assert.equal(b.toString(), 'xxx');
811
812 // issue GH-3416
813 Buffer(Buffer(0), 0, 0);
814
815 [ 'hex',
816   'utf8',
817   'utf-8',
818   'ascii',
819   'binary',
820   'base64',
821   'ucs2',
822   'ucs-2',
823   'utf16le',
824   'utf-16le' ].forEach(function(enc) {
825     assert.equal(Buffer.isEncoding(enc), true);
826   });
827
828 [ 'utf9',
829   'utf-7',
830   'Unicode-FTW',
831   'new gnu gun'  ].forEach(function(enc) {
832     assert.equal(Buffer.isEncoding(enc), false);
833   });
834
835
836 // GH-5110
837 (function () {
838   var buffer = new Buffer('test'),
839       string = JSON.stringify(buffer);
840
841   assert.equal(string, '{"type":"Buffer","data":[116,101,115,116]}');
842
843   assert.deepEqual(buffer, JSON.parse(string, function(key, value) {
844     return value && value.type === 'Buffer'
845       ? new Buffer(value.data)
846       : value;
847   }));
848 })();
849
850 // issue GH-4331
851 assert.throws(function() {
852   new Buffer(0xFFFFFFFF);
853 }, RangeError);
854 assert.throws(function() {
855   new Buffer(0xFFFFFFFFF);
856 }, TypeError);
857
858
859 // attempt to overflow buffers, similar to previous bug in array buffers
860 assert.throws(function() {
861   var buf = new Buffer(8);
862   buf.readFloatLE(0xffffffff);
863 }, /Trying to access beyond buffer length/);
864
865 assert.throws(function() {
866   var buf = new Buffer(8);
867   buf.writeFloatLE(0.0, 0xffffffff);
868 }, /Trying to access beyond buffer length/);
869
870 assert.throws(function() {
871   var buf = new SlowBuffer(8);
872   buf.readFloatLE(0xffffffff);
873 }, /Trying to read beyond buffer length/);
874
875 assert.throws(function() {
876   var buf = new SlowBuffer(8);
877   buf.writeFloatLE(0.0, 0xffffffff);
878 }, /Trying to write beyond buffer length/);
879
880
881 // ensure negative values can't get past offset
882 assert.throws(function() {
883   var buf = new Buffer(8);
884   buf.readFloatLE(-1);
885 }, /offset is not uint/);
886
887 assert.throws(function() {
888   var buf = new Buffer(8);
889   buf.writeFloatLE(0.0, -1);
890 }, /offset is not uint/);
891
892 assert.throws(function() {
893   var buf = new SlowBuffer(8);
894   buf.readFloatLE(-1);
895 }, /offset is not uint/);
896
897 assert.throws(function() {
898   var buf = new SlowBuffer(8);
899   buf.writeFloatLE(0.0, -1);
900 }, /offset is not uint/);
901
902 // offset checks
903 var buf = new Buffer(0);
904
905 assert.throws(function() { buf.readUInt8(0); }, /beyond buffer length/);
906 assert.throws(function() { buf.readInt8(0); }, /beyond buffer length/);
907
908 [16, 32].forEach(function(bits) {
909   var buf = new Buffer(bits / 8 - 1);
910
911   assert.throws(
912     function() { buf['readUInt' + bits + 'BE'](0); },
913     /beyond buffer length/,
914     'readUInt' + bits + 'BE'
915   );
916
917   assert.throws(
918     function() { buf['readUInt' + bits + 'LE'](0); },
919     /beyond buffer length/,
920     'readUInt' + bits + 'LE'
921   );
922
923   assert.throws(
924     function() { buf['readInt' + bits + 'BE'](0); },
925     /beyond buffer length/,
926     'readInt' + bits + 'BE()'
927   );
928
929   assert.throws(
930     function() { buf['readInt' + bits + 'LE'](0); },
931     /beyond buffer length/,
932     'readInt' + bits + 'LE()'
933   );
934 });
935
936 // SlowBuffer sanity checks.
937 assert.throws(function() {
938   var len = 0xfffff;
939   var sbuf = new SlowBuffer(len);
940   var buf = new Buffer(sbuf, len, 0);
941   SlowBuffer.makeFastBuffer(sbuf, buf, -len, len);  // Should throw.
942   for (var i = 0; i < len; ++i) buf[i] = 0x42;      // Try to force segfault.
943 }, RangeError);
944
945 assert.throws(function() {
946   var len = 0xfffff;
947   var sbuf = new SlowBuffer(len);
948   var buf = new Buffer(sbuf, len, -len);           // Should throw.
949   for (var i = 0; i < len; ++i) buf[i] = 0x42;     // Try to force segfault.
950 }, RangeError);
951
952 assert.throws(function() {
953   var sbuf = new SlowBuffer(1);
954   var buf = new Buffer(sbuf, 1, 0);
955   buf.length = 0xffffffff;
956   buf.slice(0xffffff0, 0xffffffe);                  // Should throw.
957 }, Error);
958
959 (function() {
960   var buf = new Buffer('0123456789');
961   assert.equal(buf.slice(-10, 10), '0123456789');
962   assert.equal(buf.slice(-20, 10), '0123456789');
963   assert.equal(buf.slice(-20, -10), '');
964   assert.equal(buf.slice(0, -1), '012345678');
965   assert.equal(buf.slice(2, -2), '234567');
966   assert.equal(buf.slice(0, 65536), '0123456789');
967   assert.equal(buf.slice(65536, 0), '');
968   for (var i = 0, s = buf.toString(); i < buf.length; ++i) {
969     assert.equal(buf.slice(-i), s.slice(-i));
970     assert.equal(buf.slice(0, -i), s.slice(0, -i));
971   }
972 })();