Fix invalid end handling for SlowBuffer#hexSlice
[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 Buffer = require('buffer').Buffer;
26
27 var b = Buffer(1024); // safe constructor
28
29 console.log('b.length == ' + b.length);
30 assert.strictEqual(1024, b.length);
31
32 b[0] = -1;
33 assert.equal(b[0], 255);
34
35 for (var i = 0; i < 1024; i++) {
36   b[i] = i % 256;
37 }
38
39 for (var i = 0; i < 1024; i++) {
40   assert.equal(i % 256, b[i]);
41 }
42
43 var c = new Buffer(512);
44 console.log('c.length == %d', c.length);
45 assert.strictEqual(512, c.length);
46
47 // copy 512 bytes, from 0 to 512.
48 var copied = b.copy(c, 0, 0, 512);
49 console.log('copied ' + copied + ' bytes from b into c');
50 assert.equal(512, copied);
51 for (var i = 0; i < c.length; i++) {
52   common.print('.');
53   assert.equal(i % 256, c[i]);
54 }
55 console.log('');
56
57 // try to copy 513 bytes, and hope we don't overrun c, which is only 512 long
58 var copied = b.copy(c, 0, 0, 513);
59 console.log('copied ' + copied + ' bytes from b into c');
60 assert.strictEqual(512, copied);
61 for (var i = 0; i < c.length; i++) {
62   assert.equal(i % 256, c[i]);
63 }
64
65 // copy all of c back into b, without specifying sourceEnd
66 var copied = c.copy(b, 0, 0);
67 console.log('copied ' + copied + ' bytes from c back into b');
68 assert.strictEqual(512, copied);
69 for (var i = 0; i < b.length; i++) {
70   assert.equal(i % 256, b[i]);
71 }
72
73 // copy 768 bytes from b into b
74 var copied = b.copy(b, 0, 256, 1024);
75 console.log('copied ' + copied + ' bytes from b into c');
76 assert.strictEqual(768, copied);
77 for (var i = 0; i < c.length; i++) {
78   assert.equal(i % 256, c[i]);
79 }
80
81 var caught_error = null;
82
83 // try to copy from before the beginning of b
84 caught_error = null;
85 try {
86   var copied = b.copy(c, 0, 100, 10);
87 } catch (err) {
88   caught_error = err;
89 }
90 assert.strictEqual('sourceEnd < sourceStart', caught_error.message);
91
92 // try to copy to before the beginning of c
93 caught_error = null;
94 try {
95   var copied = b.copy(c, -1, 0, 10);
96 } catch (err) {
97   caught_error = err;
98 }
99 assert.strictEqual('targetStart out of bounds', caught_error.message);
100
101 // try to copy to after the end of c
102 caught_error = null;
103 try {
104   var copied = b.copy(c, 512, 0, 10);
105 } catch (err) {
106   caught_error = err;
107 }
108 assert.strictEqual('targetStart out of bounds', caught_error.message);
109
110 // try to copy starting before the beginning of b
111 caught_error = null;
112 try {
113   var copied = b.copy(c, 0, -1, 1);
114 } catch (err) {
115   caught_error = err;
116 }
117 assert.strictEqual('sourceStart out of bounds', caught_error.message);
118
119 // try to copy starting after the end of b
120 caught_error = null;
121 try {
122   var copied = b.copy(c, 0, 1024, 1025);
123 } catch (err) {
124   caught_error = err;
125 }
126 assert.strictEqual('sourceStart out of bounds', caught_error.message);
127
128 // a too-low sourceEnd will get caught by earlier checks
129
130 // try to copy ending after the end of b
131 try {
132   var copied = b.copy(c, 0, 1023, 1025);
133 } catch (err) {
134   caught_error = err;
135 }
136 assert.strictEqual('sourceEnd out of bounds', caught_error.message);
137
138 // try to create 0-length buffers
139 new Buffer('');
140 new Buffer('', 'ascii');
141 new Buffer('', 'binary');
142 new Buffer(0);
143
144 // try to write a 0-length string beyond the end of b
145 b.write('', 1024);
146 b.write('', 2048);
147
148 // try to copy 0 bytes worth of data into an empty buffer
149 b.copy(new Buffer(0), 0, 0, 0);
150
151 // try to copy 0 bytes past the end of the target buffer
152 b.copy(new Buffer(0), 1, 1, 1);
153 b.copy(new Buffer(1), 1, 1, 1);
154
155 // try to copy 0 bytes from past the end of the source buffer
156 b.copy(new Buffer(1), 0, 2048, 2048);
157
158 // try to toString() a 0-length slice of a buffer, both within and without the
159 // valid buffer range
160 assert.equal(new Buffer('abc').toString('ascii', 0, 0), '');
161 assert.equal(new Buffer('abc').toString('ascii', -100, -100), '');
162 assert.equal(new Buffer('abc').toString('ascii', 100, 100), '');
163
164 // try toString() with a object as a encoding
165 assert.equal(new Buffer('abc').toString({toString: function() {
166   return 'ascii';
167 }}), 'abc');
168
169 // testing for smart defaults and ability to pass string values as offset
170 var writeTest = new Buffer('abcdes');
171 writeTest.write('n', 'ascii');
172 writeTest.write('o', 'ascii', '1');
173 writeTest.write('d', '2', 'ascii');
174 writeTest.write('e', 3, 'ascii');
175 writeTest.write('j', 'ascii', 4);
176 assert.equal(writeTest.toString(), 'nodejs');
177
178 var asciiString = 'hello world';
179 var offset = 100;
180 for (var j = 0; j < 500; j++) {
181
182   for (var i = 0; i < asciiString.length; i++) {
183     b[i] = asciiString.charCodeAt(i);
184   }
185   var asciiSlice = b.toString('ascii', 0, asciiString.length);
186   assert.equal(asciiString, asciiSlice);
187
188   var written = b.write(asciiString, offset, 'ascii');
189   assert.equal(asciiString.length, written);
190   var asciiSlice = b.toString('ascii', offset, offset + asciiString.length);
191   assert.equal(asciiString, asciiSlice);
192
193   var sliceA = b.slice(offset, offset + asciiString.length);
194   var sliceB = b.slice(offset, offset + asciiString.length);
195   for (var i = 0; i < asciiString.length; i++) {
196     assert.equal(sliceA[i], sliceB[i]);
197   }
198
199   // TODO utf8 slice tests
200 }
201
202
203 for (var j = 0; j < 100; j++) {
204   var slice = b.slice(100, 150);
205   assert.equal(50, slice.length);
206   for (var i = 0; i < 50; i++) {
207     assert.equal(b[100 + i], slice[i]);
208   }
209 }
210
211
212
213 // Bug regression test
214 var testValue = '\u00F6\u65E5\u672C\u8A9E'; // ö日本語
215 var buffer = new Buffer(32);
216 var size = buffer.write(testValue, 0, 'utf8');
217 console.log('bytes written to buffer: ' + size);
218 var slice = buffer.toString('utf8', 0, size);
219 assert.equal(slice, testValue);
220
221
222 // Test triple  slice
223 var a = new Buffer(8);
224 for (var i = 0; i < 8; i++) a[i] = i;
225 var b = a.slice(4, 8);
226 assert.equal(4, b[0]);
227 assert.equal(5, b[1]);
228 assert.equal(6, b[2]);
229 assert.equal(7, b[3]);
230 var c = b.slice(2, 4);
231 assert.equal(6, c[0]);
232 assert.equal(7, c[1]);
233
234
235 var d = new Buffer([23, 42, 255]);
236 assert.equal(d.length, 3);
237 assert.equal(d[0], 23);
238 assert.equal(d[1], 42);
239 assert.equal(d[2], 255);
240 assert.deepEqual(d, new Buffer(d));
241
242 var e = new Buffer('über');
243 console.error('uber: \'%s\'', e.toString());
244 assert.deepEqual(e, new Buffer([195, 188, 98, 101, 114]));
245
246 var f = new Buffer('über', 'ascii');
247 console.error('f.length: %d     (should be 4)', f.length);
248 assert.deepEqual(f, new Buffer([252, 98, 101, 114]));
249
250 var f = new Buffer('über', 'ucs2');
251 console.error('f.length: %d     (should be 8)', f.length);
252 assert.deepEqual(f, new Buffer([252, 0, 98, 0, 101, 0, 114, 0]));
253
254 var f = new Buffer('привет', 'ucs2');
255 console.error('f.length: %d     (should be 12)', f.length);
256 assert.deepEqual(f, new Buffer([63, 4, 64, 4, 56, 4, 50, 4, 53, 4, 66, 4]));
257 assert.equal(f.toString('ucs2'), 'привет');
258
259
260 var arrayIsh = {0: 0, 1: 1, 2: 2, 3: 3, length: 4};
261 var g = new Buffer(arrayIsh);
262 assert.deepEqual(g, new Buffer([0, 1, 2, 3]));
263 var strArrayIsh = {0: '0', 1: '1', 2: '2', 3: '3', length: 4};
264 g = new Buffer(strArrayIsh);
265 assert.deepEqual(g, new Buffer([0, 1, 2, 3]));
266
267
268 //
269 // Test toString('base64')
270 //
271 assert.equal('TWFu', (new Buffer('Man')).toString('base64'));
272 // big example
273 var quote = 'Man is distinguished, not only by his reason, but by this ' +
274             'singular passion from other animals, which is a lust ' +
275             'of the mind, that by a perseverance of delight in the continued ' +
276             'and indefatigable generation of knowledge, exceeds the short ' +
277             'vehemence of any carnal pleasure.';
278 var expected = 'TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24s' +
279                'IGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltY' +
280                'WxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZX' +
281                'JzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmR' +
282                'lZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo' +
283                'ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=';
284 assert.equal(expected, (new Buffer(quote)).toString('base64'));
285
286
287 b = new Buffer(1024);
288 var bytesWritten = b.write(expected, 0, 'base64');
289 assert.equal(quote.length, bytesWritten);
290 assert.equal(quote, b.toString('ascii', 0, quote.length));
291
292 // check that the base64 decoder ignores whitespace
293 var expectedWhite = expected.slice(0, 60) + ' \n' +
294                     expected.slice(60, 120) + ' \n' +
295                     expected.slice(120, 180) + ' \n' +
296                     expected.slice(180, 240) + ' \n' +
297                     expected.slice(240, 300) + '\n' +
298                     expected.slice(300, 360) + '\n';
299 b = new Buffer(1024);
300 bytesWritten = b.write(expectedWhite, 0, 'base64');
301 assert.equal(quote.length, bytesWritten);
302 assert.equal(quote, b.toString('ascii', 0, quote.length));
303
304 // check that the base64 decoder on the constructor works
305 // even in the presence of whitespace.
306 b = new Buffer(expectedWhite, 'base64');
307 assert.equal(quote.length, b.length);
308 assert.equal(quote, b.toString('ascii', 0, quote.length));
309
310 // check that the base64 decoder ignores illegal chars
311 var expectedIllegal = expected.slice(0, 60) + ' \x80' +
312                       expected.slice(60, 120) + ' \xff' +
313                       expected.slice(120, 180) + ' \x00' +
314                       expected.slice(180, 240) + ' \x98' +
315                       expected.slice(240, 300) + '\x03' +
316                       expected.slice(300, 360);
317 b = new Buffer(expectedIllegal, 'base64');
318 assert.equal(quote.length, b.length);
319 assert.equal(quote, b.toString('ascii', 0, quote.length));
320
321
322 assert.equal(new Buffer('', 'base64').toString(), '');
323 assert.equal(new Buffer('K', 'base64').toString(), '');
324
325 // multiple-of-4 with padding
326 assert.equal(new Buffer('Kg==', 'base64').toString(), '*');
327 assert.equal(new Buffer('Kio=', 'base64').toString(), '**');
328 assert.equal(new Buffer('Kioq', 'base64').toString(), '***');
329 assert.equal(new Buffer('KioqKg==', 'base64').toString(), '****');
330 assert.equal(new Buffer('KioqKio=', 'base64').toString(), '*****');
331 assert.equal(new Buffer('KioqKioq', 'base64').toString(), '******');
332 assert.equal(new Buffer('KioqKioqKg==', 'base64').toString(), '*******');
333 assert.equal(new Buffer('KioqKioqKio=', 'base64').toString(), '********');
334 assert.equal(new Buffer('KioqKioqKioq', 'base64').toString(), '*********');
335 assert.equal(new Buffer('KioqKioqKioqKg==', 'base64').toString(),
336              '**********');
337 assert.equal(new Buffer('KioqKioqKioqKio=', 'base64').toString(),
338              '***********');
339 assert.equal(new Buffer('KioqKioqKioqKioq', 'base64').toString(),
340              '************');
341 assert.equal(new Buffer('KioqKioqKioqKioqKg==', 'base64').toString(),
342              '*************');
343 assert.equal(new Buffer('KioqKioqKioqKioqKio=', 'base64').toString(),
344              '**************');
345 assert.equal(new Buffer('KioqKioqKioqKioqKioq', 'base64').toString(),
346              '***************');
347 assert.equal(new Buffer('KioqKioqKioqKioqKioqKg==', 'base64').toString(),
348              '****************');
349 assert.equal(new Buffer('KioqKioqKioqKioqKioqKio=', 'base64').toString(),
350              '*****************');
351 assert.equal(new Buffer('KioqKioqKioqKioqKioqKioq', 'base64').toString(),
352              '******************');
353 assert.equal(new Buffer('KioqKioqKioqKioqKioqKioqKg==', 'base64').toString(),
354              '*******************');
355 assert.equal(new Buffer('KioqKioqKioqKioqKioqKioqKio=', 'base64').toString(),
356              '********************');
357
358 // no padding, not a multiple of 4
359 assert.equal(new Buffer('Kg', 'base64').toString(), '*');
360 assert.equal(new Buffer('Kio', 'base64').toString(), '**');
361 assert.equal(new Buffer('KioqKg', 'base64').toString(), '****');
362 assert.equal(new Buffer('KioqKio', 'base64').toString(), '*****');
363 assert.equal(new Buffer('KioqKioqKg', 'base64').toString(), '*******');
364 assert.equal(new Buffer('KioqKioqKio', 'base64').toString(), '********');
365 assert.equal(new Buffer('KioqKioqKioqKg', 'base64').toString(), '**********');
366 assert.equal(new Buffer('KioqKioqKioqKio', 'base64').toString(), '***********');
367 assert.equal(new Buffer('KioqKioqKioqKioqKg', 'base64').toString(),
368              '*************');
369 assert.equal(new Buffer('KioqKioqKioqKioqKio', 'base64').toString(),
370              '**************');
371 assert.equal(new Buffer('KioqKioqKioqKioqKioqKg', 'base64').toString(),
372              '****************');
373 assert.equal(new Buffer('KioqKioqKioqKioqKioqKio', 'base64').toString(),
374              '*****************');
375 assert.equal(new Buffer('KioqKioqKioqKioqKioqKioqKg', 'base64').toString(),
376              '*******************');
377 assert.equal(new Buffer('KioqKioqKioqKioqKioqKioqKio', 'base64').toString(),
378              '********************');
379
380 // handle padding graciously, multiple-of-4 or not
381 assert.equal(new Buffer('72INjkR5fchcxk9+VgdGPFJDxUBFR5/rMFsghgxADiw==',
382                         'base64').length, 32);
383 assert.equal(new Buffer('72INjkR5fchcxk9+VgdGPFJDxUBFR5/rMFsghgxADiw=',
384                         'base64').length, 32);
385 assert.equal(new Buffer('72INjkR5fchcxk9+VgdGPFJDxUBFR5/rMFsghgxADiw',
386                         'base64').length, 32);
387 assert.equal(new Buffer('w69jACy6BgZmaFvv96HG6MYksWytuZu3T1FvGnulPg==',
388                         'base64').length, 31);
389 assert.equal(new Buffer('w69jACy6BgZmaFvv96HG6MYksWytuZu3T1FvGnulPg=',
390                         'base64').length, 31);
391 assert.equal(new Buffer('w69jACy6BgZmaFvv96HG6MYksWytuZu3T1FvGnulPg',
392                         'base64').length, 31);
393
394 // This string encodes single '.' character in UTF-16
395 var dot = new Buffer('//4uAA==', 'base64');
396 assert.equal(dot[0], 0xff);
397 assert.equal(dot[1], 0xfe);
398 assert.equal(dot[2], 0x2e);
399 assert.equal(dot[3], 0x00);
400 assert.equal(dot.toString('base64'), '//4uAA==');
401
402
403 // Creating buffers larger than pool size.
404 var l = Buffer.poolSize + 5;
405 var s = '';
406 for (i = 0; i < l; i++) {
407   s += 'h';
408 }
409
410 var b = new Buffer(s);
411
412 for (i = 0; i < l; i++) {
413   assert.equal('h'.charCodeAt(0), b[i]);
414 }
415
416 var sb = b.toString();
417 assert.equal(sb.length, s.length);
418 assert.equal(sb, s);
419
420
421 // Single argument slice
422 b = new Buffer('abcde');
423 assert.equal('bcde', b.slice(1).toString());
424
425 // byte length
426 assert.equal(14, Buffer.byteLength('Il était tué'));
427 assert.equal(14, Buffer.byteLength('Il était tué', 'utf8'));
428 assert.equal(24, Buffer.byteLength('Il était tué', 'ucs2'));
429 assert.equal(12, Buffer.byteLength('Il était tué', 'ascii'));
430 assert.equal(12, Buffer.byteLength('Il était tué', 'binary'));
431
432 // slice(0,0).length === 0
433 assert.equal(0, Buffer('hello').slice(0, 0).length);
434
435 // test hex toString
436 console.log('Create hex string from buffer');
437 var hexb = new Buffer(256);
438 for (var i = 0; i < 256; i ++) {
439   hexb[i] = i;
440 }
441 var hexStr = hexb.toString('hex');
442 assert.equal(hexStr,
443              '000102030405060708090a0b0c0d0e0f'+
444              '101112131415161718191a1b1c1d1e1f'+
445              '202122232425262728292a2b2c2d2e2f'+
446              '303132333435363738393a3b3c3d3e3f'+
447              '404142434445464748494a4b4c4d4e4f'+
448              '505152535455565758595a5b5c5d5e5f'+
449              '606162636465666768696a6b6c6d6e6f'+
450              '707172737475767778797a7b7c7d7e7f'+
451              '808182838485868788898a8b8c8d8e8f'+
452              '909192939495969798999a9b9c9d9e9f'+
453              'a0a1a2a3a4a5a6a7a8a9aaabacadaeaf'+
454              'b0b1b2b3b4b5b6b7b8b9babbbcbdbebf'+
455              'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf'+
456              'd0d1d2d3d4d5d6d7d8d9dadbdcdddedf'+
457              'e0e1e2e3e4e5e6e7e8e9eaebecedeeef'+
458              'f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff');
459
460 console.log('Create buffer from hex string');
461 var hexb2 = new Buffer(hexStr, 'hex');
462 for (var i = 0; i < 256; i ++) {
463   assert.equal(hexb2[i], hexb[i]);
464 }
465
466 // test an invalid slice end.
467 console.log('Try to slice off the end of the buffer');
468 var b = new Buffer([1,2,3,4,5]);
469 var b2 = b.toString('hex', 1, 10000);
470 var b3 = b.toString('hex', 1, 5);
471 var b4 = b.toString('hex', 1);
472 assert.equal(b2, b3);
473 assert.equal(b2, b4);