Skip to content
File

Blob: src/workerd/api/node/tests/buffer-nodejs-test.js

javascript6265 lines
1// Copyright (c) 2017-2022 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4//
5// Adapted from Node.js. Copyright Joyent, Inc. and other Node contributors.
6//
7// Permission is hereby granted, free of charge, to any person obtaining a
8// copy of this software and associated documentation files (the
9// "Software"), to deal in the Software without restriction, including
10// without limitation the rights to use, copy, modify, merge, publish,
11// distribute, sublicense, and/or sell copies of the Software, and to permit
12// persons to whom the Software is furnished to do so, subject to the
13// following conditions:
14//
15// The above copyright notice and this permission notice shall be included
16// in all copies or substantial portions of the Software.
17//
18// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
21// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
22// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24// USE OR OTHER DEALINGS IN THE SOFTWARE.
25 
26import {
27 deepStrictEqual,
28 notDeepStrictEqual,
29 notStrictEqual,
30 ok,
31 strictEqual,
32 throws,
33} from 'node:assert';
34import util from 'node:util';
35 
36import {
37 Buffer,
38 File,
39 SlowBuffer,
40 constants,
41 isAscii,
42 isUtf8,
43 kMaxLength,
44 kStringMaxLength,
45 transcode,
46} from 'node:buffer';
47 
48import * as buffer from 'node:buffer';
49if (
50 buffer.Buffer !== Buffer ||
51 buffer.SlowBuffer !== SlowBuffer ||
52 buffer.kMaxLength !== kMaxLength ||
53 buffer.kStringMaxLength !== kStringMaxLength ||
54 buffer.constants !== constants
55) {
56 throw new Error('Incorrect default exports');
57}
58 
59const { MAX_LENGTH, MAX_STRING_LENGTH } = constants;
60 
61export const simpleAlloc = {
62 // test-buffer-alloc.js
63 test(ctrl, env, ctx) {
64 const b = Buffer.allocUnsafe(1024);
65 strictEqual(b.length, 1024);
66 
67 b[0] = -1;
68 strictEqual(b[0], 255);
69 
70 for (let i = 0; i < 1024; i++) {
71 b[i] = i % 256;
72 }
73 
74 for (let i = 0; i < 1024; i++) {
75 strictEqual(i % 256, b[i]);
76 }
77 
78 const c = Buffer.allocUnsafe(512);
79 strictEqual(c.length, 512);
80 
81 const d = Buffer.from([]);
82 strictEqual(d.length, 0);
83 },
84};
85 
86export const offsetProperties = {
87 test(ctrl, env, ctx) {
88 const b = Buffer.alloc(128);
89 strictEqual(b.length, 128);
90 strictEqual(b.byteOffset, 0);
91 strictEqual(b.offset, 0);
92 },
93};
94 
95export const bufferFromUint8Array = {
96 test(ctrl, env, ctx) {
97 {
98 const ui8 = new Uint8Array(4).fill(42);
99 const e = Buffer.from(ui8);
100 for (const [index, value] of e.entries()) {
101 strictEqual(value, ui8[index]);
102 }
103 }
104 
105 {
106 const ui8 = new Uint8Array(4).fill(42);
107 const e = Buffer(ui8);
108 for (const [key, value] of e.entries()) {
109 strictEqual(value, ui8[key]);
110 }
111 }
112 },
113};
114 
115export const bufferFromUint32Array = {
116 test(ctrl, env, ctx) {
117 {
118 const ui32 = new Uint32Array(4).fill(42);
119 const e = Buffer.from(ui32);
120 for (const [index, value] of e.entries()) {
121 strictEqual(value, ui32[index]);
122 }
123 }
124 {
125 const ui32 = new Uint32Array(4).fill(42);
126 const e = Buffer(ui32);
127 for (const [key, value] of e.entries()) {
128 strictEqual(value, ui32[key]);
129 }
130 }
131 },
132};
133 
134export const invalidEncodingForToString = {
135 test(ctrl, env, ctx) {
136 const b = Buffer.allocUnsafe(10);
137 // Test invalid encoding for Buffer.toString
138 throws(() => b.toString('invalid'), /Unknown encoding: invalid/);
139 // // Invalid encoding for Buffer.write
140 throws(
141 () => b.write('test string', 0, 5, 'invalid'),
142 /Unknown encoding: invalid/
143 );
144 // Unsupported arguments for Buffer.write
145 
146 throws(() => b.write('test', 'utf8', 0), { code: 'ERR_INVALID_ARG_TYPE' });
147 },
148};
149 
150export const toStringWithUndefinedEncoding = {
151 test(ctrl, env, ctx) {
152 // Test that Buffer.toString with undefined encoding defaults to utf8
153 const buf = Buffer.from('hello world');
154 strictEqual(buf.toString(undefined), 'hello world');
155 strictEqual(buf.toString(undefined), buf.toString('utf8'));
156 
157 // Test with UTF-8 characters
158 const utf8Buf = Buffer.from('¡hέlló wôrld!');
159 strictEqual(utf8Buf.toString(undefined), '¡hέlló wôrld!');
160 strictEqual(utf8Buf.toString(undefined), utf8Buf.toString('utf8'));
161 
162 // Test with start and end parameters
163 const sliceBuf = Buffer.from('hello world');
164 strictEqual(sliceBuf.toString(undefined, 0, 5), 'hello');
165 strictEqual(sliceBuf.toString(undefined, 6), 'world');
166 strictEqual(
167 sliceBuf.toString(undefined, 0, 5),
168 sliceBuf.toString('utf8', 0, 5)
169 );
170 },
171};
172 
173export const zeroLengthBuffers = {
174 test(ctrl, env, ctx) {
175 Buffer.from('');
176 Buffer.from('', 'ascii');
177 Buffer.from('', 'latin1');
178 Buffer.alloc(0);
179 Buffer.allocUnsafe(0);
180 new Buffer('');
181 new Buffer('', 'ascii');
182 new Buffer('', 'latin1');
183 new Buffer('', 'binary');
184 Buffer(0);
185 },
186};
187 
188export const outOfBoundsWrites = {
189 test(ctrl, env, ctx) {
190 const outOfRangeError = {
191 code: 'ERR_OUT_OF_RANGE',
192 name: 'RangeError',
193 };
194 
195 const b = Buffer.alloc(1024);
196 
197 // Try to write a 0-length string beyond the end of b
198 throws(() => b.write('', 2048), outOfRangeError);
199 
200 // Throw when writing to negative offset
201 throws(() => b.write('a', -1), outOfRangeError);
202 
203 // Throw when writing past bounds from the pool
204 throws(() => b.write('a', 2048), outOfRangeError);
205 
206 // Throw when writing to negative offset
207 throws(() => b.write('a', -1), outOfRangeError);
208 
209 // Try to copy 0 bytes worth of data into an empty buffer
210 b.copy(Buffer.alloc(0), 0, 0, 0);
211 
212 // Try to copy 0 bytes past the end of the target buffer
213 b.copy(Buffer.alloc(0), 1, 1, 1);
214 b.copy(Buffer.alloc(1), 1, 1, 1);
215 
216 // Try to copy 0 bytes from past the end of the source buffer
217 b.copy(Buffer.alloc(1), 0, 2048, 2048);
218 
219 Buffer.alloc(1).write('', 1, 0);
220 },
221};
222 
223export const smartDefaults = {
224 test(ctrl, env, ctx) {
225 const writeTest = Buffer.from('abcdes');
226 writeTest.write('n', 'ascii');
227 throws(() => writeTest.write('o', '1', 'ascii'), {
228 code: 'ERR_INVALID_ARG_TYPE',
229 });
230 writeTest.write('o', 1, 'ascii');
231 writeTest.write('d', 2, 'ascii');
232 writeTest.write('e', 3, 'ascii');
233 writeTest.write('j', 4, 'ascii');
234 strictEqual(writeTest.toString(), 'nodejs');
235 },
236};
237 
238export const asciiSlice = {
239 test(ctrl, env, ctx) {
240 const b = Buffer.alloc(1024);
241 
242 {
243 const asciiString = 'hello world';
244 
245 for (let i = 0; i < asciiString.length; i++) {
246 b[i] = asciiString.charCodeAt(i);
247 }
248 const asciiSlice = b.toString('ascii', 0, asciiString.length);
249 strictEqual(asciiString, asciiSlice);
250 }
251 
252 {
253 const asciiString = 'hello world';
254 const offset = 100;
255 
256 strictEqual(asciiString.length, b.write(asciiString, offset, 'ascii'));
257 const asciiSlice = b.toString(
258 'ascii',
259 offset,
260 offset + asciiString.length
261 );
262 strictEqual(asciiString, asciiSlice);
263 }
264 
265 {
266 const asciiString = 'hello world';
267 const offset = 100;
268 
269 const sliceA = b.slice(offset, offset + asciiString.length);
270 const sliceB = b.slice(offset, offset + asciiString.length);
271 for (let i = 0; i < asciiString.length; i++) {
272 strictEqual(sliceA[i], sliceB[i]);
273 }
274 }
275 },
276};
277 
278export const utf8Slice = {
279 test(ctrl, env, ctx) {
280 const b = Buffer.alloc(1024);
281 {
282 const utf8String = '¡hέlló wôrld!';
283 const offset = 100;
284 
285 b.write(utf8String, 0, Buffer.byteLength(utf8String), 'utf8');
286 let utf8Slice = b.toString('utf8', 0, Buffer.byteLength(utf8String));
287 strictEqual(utf8String, utf8Slice);
288 
289 strictEqual(
290 Buffer.byteLength(utf8String),
291 b.write(utf8String, offset, 'utf8')
292 );
293 utf8Slice = b.toString(
294 'utf8',
295 offset,
296 offset + Buffer.byteLength(utf8String)
297 );
298 strictEqual(utf8String, utf8Slice);
299 
300 const sliceA = b.slice(offset, offset + Buffer.byteLength(utf8String));
301 const sliceB = b.slice(offset, offset + Buffer.byteLength(utf8String));
302 for (let i = 0; i < Buffer.byteLength(utf8String); i++) {
303 strictEqual(sliceA[i], sliceB[i]);
304 }
305 }
306 {
307 const slice = b.slice(100, 150);
308 strictEqual(slice.length, 50);
309 for (let i = 0; i < 50; i++) {
310 strictEqual(b[100 + i], slice[i]);
311 }
312 }
313 
314 {
315 // Make sure only top level parent propagates from allocPool
316 // (We don't actually implement pooling, this is just carried over from Node.js)
317 const b = Buffer.allocUnsafe(5);
318 const c = b.slice(0, 4);
319 const d = c.slice(0, 2);
320 strictEqual(b.parent, c.parent);
321 strictEqual(b.parent, d.parent);
322 }
323 
324 {
325 // Also from a non-pooled instance
326 const b = Buffer.allocUnsafeSlow(5);
327 const c = b.slice(0, 4);
328 const d = c.slice(0, 2);
329 strictEqual(c.parent, d.parent);
330 }
331 
332 {
333 // Bug regression test
334 const testValue = '\u00F6\u65E5\u672C\u8A9E'; // ö日本語
335 const buffer = Buffer.allocUnsafe(32);
336 const size = buffer.write(testValue, 0, 'utf8');
337 const slice = buffer.toString('utf8', 0, size);
338 strictEqual(slice, testValue);
339 }
340 
341 {
342 // Test triple slice
343 const a = Buffer.allocUnsafe(8);
344 for (let i = 0; i < 8; i++) a[i] = i;
345 const b = a.slice(4, 8);
346 strictEqual(b[0], 4);
347 strictEqual(b[1], 5);
348 strictEqual(b[2], 6);
349 strictEqual(b[3], 7);
350 const c = b.slice(2, 4);
351 strictEqual(c[0], 6);
352 strictEqual(c[1], 7);
353 }
354 },
355};
356 
357export const bufferFrom = {
358 test(ctrl, env, ctx) {
359 {
360 const d = Buffer.from([23, 42, 255]);
361 strictEqual(d.length, 3);
362 strictEqual(d[0], 23);
363 strictEqual(d[1], 42);
364 strictEqual(d[2], 255);
365 deepStrictEqual(d, Buffer.from(d));
366 }
367 {
368 // Test for proper UTF-8 Encoding
369 const e = Buffer.from('über');
370 deepStrictEqual(e, Buffer.from([195, 188, 98, 101, 114]));
371 }
372 {
373 // Test for proper ascii Encoding, length should be 4
374 const f = Buffer.from('über', 'ascii');
375 deepStrictEqual(f, Buffer.from([252, 98, 101, 114]));
376 }
377 ['ucs2', 'ucs-2', 'utf16le', 'utf-16le'].forEach((encoding) => {
378 {
379 // Test for proper UTF16LE encoding, length should be 8
380 const f = Buffer.from('über', encoding);
381 deepStrictEqual(f, Buffer.from([252, 0, 98, 0, 101, 0, 114, 0]));
382 }
383 
384 {
385 // Length should be 12
386 const f = Buffer.from('привет', encoding);
387 deepStrictEqual(
388 f,
389 Buffer.from([63, 4, 64, 4, 56, 4, 50, 4, 53, 4, 66, 4])
390 );
391 strictEqual(f.toString(encoding), 'привет');
392 }
393 
394 {
395 const f = Buffer.from([0, 0, 0, 0, 0]);
396 strictEqual(f.length, 5);
397 const size = f.write('あいうえお', encoding);
398 strictEqual(size, 4);
399 deepStrictEqual(f, Buffer.from([0x42, 0x30, 0x44, 0x30, 0x00]));
400 }
401 
402 {
403 const f = Buffer.from('\uD83D\uDC4D', 'utf-16le'); // THUMBS UP SIGN (U+1F44D)
404 strictEqual(f.length, 4);
405 deepStrictEqual(f, Buffer.from('3DD84DDC', 'hex'));
406 }
407 
408 {
409 const arrayIsh = { 0: 0, 1: 1, 2: 2, 3: 3, length: 4 };
410 let g = Buffer.from(arrayIsh);
411 deepStrictEqual(g, Buffer.from([0, 1, 2, 3]));
412 const strArrayIsh = { 0: '0', 1: '1', 2: '2', 3: '3', length: 4 };
413 g = Buffer.from(strArrayIsh);
414 deepStrictEqual(g, Buffer.from([0, 1, 2, 3]));
415 }
416 });
417 
418 {
419 const checkString = 'test';
420 
421 const check = Buffer.from(checkString);
422 
423 class MyString extends String {
424 constructor() {
425 super(checkString);
426 }
427 }
428 
429 class MyPrimitive {
430 [Symbol.toPrimitive]() {
431 return checkString;
432 }
433 }
434 
435 class MyBadPrimitive {
436 [Symbol.toPrimitive]() {
437 return 1;
438 }
439 }
440 
441 deepStrictEqual(Buffer.from(new String(checkString)), check);
442 deepStrictEqual(Buffer.from(new MyString()), check);
443 deepStrictEqual(Buffer.from(new MyPrimitive()), check);
444 
445 [
446 {},
447 new Boolean(true),
448 {
449 valueOf() {
450 return null;
451 },
452 },
453 {
454 valueOf() {
455 return undefined;
456 },
457 },
458 { valueOf: null },
459 { __proto__: null },
460 new Number(true),
461 new MyBadPrimitive(),
462 Symbol(),
463 5n,
464 (one, two, three) => {},
465 undefined,
466 null,
467 ].forEach((input) => {
468 const errObj = {
469 name: 'TypeError',
470 };
471 throws(() => Buffer.from(input), errObj);
472 throws(() => Buffer.from(input, 'hex'), errObj);
473 });
474 
475 Buffer.allocUnsafe(10); // Should not throw.
476 Buffer.from('deadbeaf', 'hex'); // Should not throw.
477 }
478 },
479};
480 
481export const base64 = {
482 test(ctrl, env, ctx) {
483 const base64flavors = ['base64', 'base64url'];
484 {
485 strictEqual(Buffer.from('Man').toString('base64'), 'TWFu');
486 strictEqual(Buffer.from('Woman').toString('base64'), 'V29tYW4=');
487 strictEqual(Buffer.from('Man').toString('base64url'), 'TWFu');
488 strictEqual(Buffer.from('Woman').toString('base64url'), 'V29tYW4');
489 }
490 
491 {
492 const expected = [0xff, 0xff, 0xbe, 0xff, 0xef, 0xbf, 0xfb, 0xef, 0xff];
493 deepStrictEqual(
494 Buffer.from('//++/++/++//', 'base64'),
495 Buffer.from(expected)
496 );
497 deepStrictEqual(
498 Buffer.from('__--_--_--__', 'base64'),
499 Buffer.from(expected)
500 );
501 deepStrictEqual(
502 Buffer.from('//++/++/++//', 'base64url'),
503 Buffer.from(expected)
504 );
505 deepStrictEqual(
506 Buffer.from('__--_--_--__', 'base64url'),
507 Buffer.from(expected)
508 );
509 }
510 
511 {
512 // Test that regular and URL-safe base64 both work both ways with padding
513 const expected = [
514 0xff, 0xff, 0xbe, 0xff, 0xef, 0xbf, 0xfb, 0xef, 0xff, 0xfb,
515 ];
516 deepStrictEqual(
517 Buffer.from('//++/++/++//+w==', 'base64'),
518 Buffer.from(expected)
519 );
520 deepStrictEqual(
521 Buffer.from('//++/++/++//+w==', 'base64'),
522 Buffer.from(expected)
523 );
524 deepStrictEqual(
525 Buffer.from('//++/++/++//+w==', 'base64url'),
526 Buffer.from(expected)
527 );
528 deepStrictEqual(
529 Buffer.from('//++/++/++//+w==', 'base64url'),
530 Buffer.from(expected)
531 );
532 }
533 
534 {
535 // big example
536 const quote =
537 'Man is distinguished, not only by his reason, but by this ' +
538 'singular passion from other animals, which is a lust ' +
539 'of the mind, that by a perseverance of delight in the ' +
540 'continued and indefatigable generation of knowledge, ' +
541 'exceeds the short vehemence of any carnal pleasure.';
542 const expected =
543 'TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb' +
544 '24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlci' +
545 'BhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQ' +
546 'gYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu' +
547 'dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZ' +
548 'GdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm' +
549 '5hbCBwbGVhc3VyZS4=';
550 strictEqual(Buffer.from(quote).toString('base64'), expected);
551 strictEqual(
552 Buffer.from(quote).toString('base64url'),
553 expected.replaceAll('+', '-').replaceAll('/', '_').replaceAll('=', '')
554 );
555 
556 base64flavors.forEach((encoding) => {
557 let b = Buffer.allocUnsafe(1024);
558 let bytesWritten = b.write(expected, 0, encoding);
559 strictEqual(quote.length, bytesWritten);
560 strictEqual(quote, b.toString('ascii', 0, quote.length));
561 
562 // Check that the base64 decoder ignores whitespace
563 const expectedWhite =
564 `${expected.slice(0, 60)} \n` +
565 `${expected.slice(60, 120)} \n` +
566 `${expected.slice(120, 180)} \n` +
567 `${expected.slice(180, 240)} \n` +
568 `${expected.slice(240, 300)}\n` +
569 `${expected.slice(300, 360)}\n`;
570 b = Buffer.allocUnsafe(1024);
571 bytesWritten = b.write(expectedWhite, 0, encoding);
572 strictEqual(quote.length, bytesWritten);
573 strictEqual(quote, b.toString('ascii', 0, quote.length));
574 
575 // Check that the base64 decoder on the constructor works
576 // even in the presence of whitespace.
577 b = Buffer.from(expectedWhite, encoding);
578 strictEqual(quote.length, b.length);
579 strictEqual(quote, b.toString('ascii', 0, quote.length));
580 
581 // Check that the base64 decoder ignores illegal chars
582 const expectedIllegal =
583 expected.slice(0, 60) +
584 ' \x80' +
585 expected.slice(60, 120) +
586 ' \xff' +
587 expected.slice(120, 180) +
588 ' \x00' +
589 expected.slice(180, 240) +
590 ' \x98' +
591 expected.slice(240, 300) +
592 '\x03' +
593 expected.slice(300, 360);
594 b = Buffer.from(expectedIllegal, encoding);
595 strictEqual(quote.length, b.length);
596 strictEqual(quote, b.toString('ascii', 0, quote.length));
597 });
598 }
599 
600 base64flavors.forEach((encoding) => {
601 strictEqual(Buffer.from('', encoding).toString(), '');
602 strictEqual(Buffer.from('K', encoding).toString(), '');
603 
604 // multiple-of-4 with padding
605 strictEqual(Buffer.from('Kg==', encoding).toString(), '*');
606 strictEqual(Buffer.from('Kio=', encoding).toString(), '*'.repeat(2));
607 strictEqual(Buffer.from('Kioq', encoding).toString(), '*'.repeat(3));
608 strictEqual(Buffer.from('KioqKg==', encoding).toString(), '*'.repeat(4));
609 strictEqual(Buffer.from('KioqKio=', encoding).toString(), '*'.repeat(5));
610 strictEqual(Buffer.from('KioqKioq', encoding).toString(), '*'.repeat(6));
611 strictEqual(
612 Buffer.from('KioqKioqKg==', encoding).toString(),
613 '*'.repeat(7)
614 );
615 strictEqual(
616 Buffer.from('KioqKioqKio=', encoding).toString(),
617 '*'.repeat(8)
618 );
619 strictEqual(
620 Buffer.from('KioqKioqKioq', encoding).toString(),
621 '*'.repeat(9)
622 );
623 strictEqual(
624 Buffer.from('KioqKioqKioqKg==', encoding).toString(),
625 '*'.repeat(10)
626 );
627 strictEqual(
628 Buffer.from('KioqKioqKioqKio=', encoding).toString(),
629 '*'.repeat(11)
630 );
631 strictEqual(
632 Buffer.from('KioqKioqKioqKioq', encoding).toString(),
633 '*'.repeat(12)
634 );
635 strictEqual(
636 Buffer.from('KioqKioqKioqKioqKg==', encoding).toString(),
637 '*'.repeat(13)
638 );
639 strictEqual(
640 Buffer.from('KioqKioqKioqKioqKio=', encoding).toString(),
641 '*'.repeat(14)
642 );
643 strictEqual(
644 Buffer.from('KioqKioqKioqKioqKioq', encoding).toString(),
645 '*'.repeat(15)
646 );
647 strictEqual(
648 Buffer.from('KioqKioqKioqKioqKioqKg==', encoding).toString(),
649 '*'.repeat(16)
650 );
651 strictEqual(
652 Buffer.from('KioqKioqKioqKioqKioqKio=', encoding).toString(),
653 '*'.repeat(17)
654 );
655 strictEqual(
656 Buffer.from('KioqKioqKioqKioqKioqKioq', encoding).toString(),
657 '*'.repeat(18)
658 );
659 strictEqual(
660 Buffer.from('KioqKioqKioqKioqKioqKioqKg==', encoding).toString(),
661 '*'.repeat(19)
662 );
663 strictEqual(
664 Buffer.from('KioqKioqKioqKioqKioqKioqKio=', encoding).toString(),
665 '*'.repeat(20)
666 );
667 
668 // No padding, not a multiple of 4
669 strictEqual(Buffer.from('Kg', encoding).toString(), '*');
670 strictEqual(Buffer.from('Kio', encoding).toString(), '*'.repeat(2));
671 strictEqual(Buffer.from('KioqKg', encoding).toString(), '*'.repeat(4));
672 strictEqual(Buffer.from('KioqKio', encoding).toString(), '*'.repeat(5));
673 strictEqual(
674 Buffer.from('KioqKioqKg', encoding).toString(),
675 '*'.repeat(7)
676 );
677 strictEqual(
678 Buffer.from('KioqKioqKio', encoding).toString(),
679 '*'.repeat(8)
680 );
681 strictEqual(
682 Buffer.from('KioqKioqKioqKg', encoding).toString(),
683 '*'.repeat(10)
684 );
685 strictEqual(
686 Buffer.from('KioqKioqKioqKio', encoding).toString(),
687 '*'.repeat(11)
688 );
689 strictEqual(
690 Buffer.from('KioqKioqKioqKioqKg', encoding).toString(),
691 '*'.repeat(13)
692 );
693 strictEqual(
694 Buffer.from('KioqKioqKioqKioqKio', encoding).toString(),
695 '*'.repeat(14)
696 );
697 strictEqual(
698 Buffer.from('KioqKioqKioqKioqKioqKg', encoding).toString(),
699 '*'.repeat(16)
700 );
701 strictEqual(
702 Buffer.from('KioqKioqKioqKioqKioqKio', encoding).toString(),
703 '*'.repeat(17)
704 );
705 strictEqual(
706 Buffer.from('KioqKioqKioqKioqKioqKioqKg', encoding).toString(),
707 '*'.repeat(19)
708 );
709 strictEqual(
710 Buffer.from('KioqKioqKioqKioqKioqKioqKio', encoding).toString(),
711 '*'.repeat(20)
712 );
713 });
714 
715 // Handle padding graciously, multiple-of-4 or not
716 strictEqual(
717 Buffer.from('72INjkR5fchcxk9+VgdGPFJDxUBFR5/rMFsghgxADiw==', 'base64')
718 .length,
719 32
720 );
721 strictEqual(
722 Buffer.from('72INjkR5fchcxk9-VgdGPFJDxUBFR5_rMFsghgxADiw==', 'base64url')
723 .length,
724 32
725 );
726 strictEqual(
727 Buffer.from('72INjkR5fchcxk9+VgdGPFJDxUBFR5/rMFsghgxADiw=', 'base64')
728 .length,
729 32
730 );
731 strictEqual(
732 Buffer.from('72INjkR5fchcxk9-VgdGPFJDxUBFR5_rMFsghgxADiw=', 'base64url')
733 .length,
734 32
735 );
736 strictEqual(
737 Buffer.from('72INjkR5fchcxk9+VgdGPFJDxUBFR5/rMFsghgxADiw', 'base64')
738 .length,
739 32
740 );
741 strictEqual(
742 Buffer.from('72INjkR5fchcxk9-VgdGPFJDxUBFR5_rMFsghgxADiw', 'base64url')
743 .length,
744 32
745 );
746 strictEqual(
747 Buffer.from('w69jACy6BgZmaFvv96HG6MYksWytuZu3T1FvGnulPg==', 'base64')
748 .length,
749 31
750 );
751 strictEqual(
752 Buffer.from('w69jACy6BgZmaFvv96HG6MYksWytuZu3T1FvGnulPg==', 'base64url')
753 .length,
754 31
755 );
756 strictEqual(
757 Buffer.from('w69jACy6BgZmaFvv96HG6MYksWytuZu3T1FvGnulPg=', 'base64')
758 .length,
759 31
760 );
761 strictEqual(
762 Buffer.from('w69jACy6BgZmaFvv96HG6MYksWytuZu3T1FvGnulPg=', 'base64url')
763 .length,
764 31
765 );
766 strictEqual(
767 Buffer.from('w69jACy6BgZmaFvv96HG6MYksWytuZu3T1FvGnulPg', 'base64')
768 .length,
769 31
770 );
771 strictEqual(
772 Buffer.from('w69jACy6BgZmaFvv96HG6MYksWytuZu3T1FvGnulPg', 'base64url')
773 .length,
774 31
775 );
776 
777 {
778 // This string encodes single '.' character in UTF-16
779 const dot = Buffer.from('//4uAA==', 'base64');
780 strictEqual(dot[0], 0xff);
781 strictEqual(dot[1], 0xfe);
782 strictEqual(dot[2], 0x2e);
783 strictEqual(dot[3], 0x00);
784 strictEqual(dot.toString('base64'), '//4uAA==');
785 }
786 
787 {
788 // This string encodes single '.' character in UTF-16
789 const dot = Buffer.from('//4uAA', 'base64url');
790 strictEqual(dot[0], 0xff);
791 strictEqual(dot[1], 0xfe);
792 strictEqual(dot[2], 0x2e);
793 strictEqual(dot[3], 0x00);
794 strictEqual(dot.toString('base64url'), '__4uAA');
795 }
796 
797 {
798 // Writing base64 at a position > 0 should not mangle the result.
799 //
800 // https://github.com/joyent/node/issues/402
801 const segments = ['TWFkbmVzcz8h', 'IFRoaXM=', 'IGlz', 'IG5vZGUuanMh'];
802 const b = Buffer.allocUnsafe(64);
803 let pos = 0;
804 
805 for (let i = 0; i < segments.length; ++i) {
806 pos += b.write(segments[i], pos, 'base64');
807 }
808 strictEqual(b.toString('latin1', 0, pos), 'Madness?! This is node.js!');
809 }
810 
811 {
812 // Writing base64url at a position > 0 should not mangle the result.
813 //
814 // https://github.com/joyent/node/issues/402
815 const segments = ['TWFkbmVzcz8h', 'IFRoaXM', 'IGlz', 'IG5vZGUuanMh'];
816 const b = Buffer.allocUnsafe(64);
817 let pos = 0;
818 
819 for (let i = 0; i < segments.length; ++i) {
820 pos += b.write(segments[i], pos, 'base64url');
821 }
822 strictEqual(b.toString('latin1', 0, pos), 'Madness?! This is node.js!');
823 }
824 
825 // Regression test for https://github.com/nodejs/node/issues/3496.
826 strictEqual(Buffer.from('=bad'.repeat(1e4), 'base64').length, 0);
827 
828 // // Regression test for https://github.com/nodejs/node/issues/11987.
829 deepStrictEqual(Buffer.from('w0 ', 'base64'), Buffer.from('w0', 'base64'));
830 
831 // // Regression test for https://github.com/nodejs/node/issues/13657.
832 deepStrictEqual(
833 Buffer.from(' YWJvcnVtLg', 'base64'),
834 Buffer.from('YWJvcnVtLg', 'base64')
835 );
836 },
837};
838 
839export const hex = {
840 test(ctrl, env, ctx) {
841 {
842 // test hex toString
843 const hexb = Buffer.allocUnsafe(256);
844 for (let i = 0; i < 256; i++) {
845 hexb[i] = i;
846 }
847 const hexStr = hexb.toString('hex');
848 strictEqual(
849 hexStr,
850 '000102030405060708090a0b0c0d0e0f' +
851 '101112131415161718191a1b1c1d1e1f' +
852 '202122232425262728292a2b2c2d2e2f' +
853 '303132333435363738393a3b3c3d3e3f' +
854 '404142434445464748494a4b4c4d4e4f' +
855 '505152535455565758595a5b5c5d5e5f' +
856 '606162636465666768696a6b6c6d6e6f' +
857 '707172737475767778797a7b7c7d7e7f' +
858 '808182838485868788898a8b8c8d8e8f' +
859 '909192939495969798999a9b9c9d9e9f' +
860 'a0a1a2a3a4a5a6a7a8a9aaabacadaeaf' +
861 'b0b1b2b3b4b5b6b7b8b9babbbcbdbebf' +
862 'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf' +
863 'd0d1d2d3d4d5d6d7d8d9dadbdcdddedf' +
864 'e0e1e2e3e4e5e6e7e8e9eaebecedeeef' +
865 'f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff'
866 );
867 
868 const hexb2 = Buffer.from(hexStr, 'hex');
869 for (let i = 0; i < 256; i++) {
870 strictEqual(hexb2[i], hexb[i]);
871 }
872 }
873 
874 // Test single hex character is discarded.
875 strictEqual(Buffer.from('A', 'hex').length, 0);
876 
877 // Test that if a trailing character is discarded, rest of string is processed.
878 deepStrictEqual(Buffer.from('Abx', 'hex'), Buffer.from('Ab', 'hex'));
879 
880 // Test single base64 char encodes as 0.
881 strictEqual(Buffer.from('A', 'base64').length, 0);
882 
883 {
884 // Test an invalid slice end.
885 const b = Buffer.from([1, 2, 3, 4, 5]);
886 const b2 = b.toString('hex', 1, 10000);
887 const b3 = b.toString('hex', 1, 5);
888 const b4 = b.toString('hex', 1);
889 strictEqual(b2, b3);
890 strictEqual(b2, b4);
891 }
892 },
893};
894 
895export const slicing = {
896 test(ctrl, env, ctx) {
897 function buildBuffer(data) {
898 if (Array.isArray(data)) {
899 const buffer = Buffer.allocUnsafe(data.length);
900 data.forEach((v, k) => (buffer[k] = v));
901 return buffer;
902 }
903 return null;
904 }
905 
906 const x = buildBuffer([
907 0x81, 0xa3, 0x66, 0x6f, 0x6f, 0xa3, 0x62, 0x61, 0x72,
908 ]);
909 
910 {
911 const z = x.slice(4);
912 strictEqual(z.length, 5);
913 strictEqual(z[0], 0x6f);
914 strictEqual(z[1], 0xa3);
915 strictEqual(z[2], 0x62);
916 strictEqual(z[3], 0x61);
917 strictEqual(z[4], 0x72);
918 }
919 
920 {
921 const z = x.slice(0);
922 strictEqual(z.length, x.length);
923 }
924 
925 {
926 const z = x.slice(0, 4);
927 strictEqual(z.length, 4);
928 strictEqual(z[0], 0x81);
929 strictEqual(z[1], 0xa3);
930 }
931 
932 {
933 const z = x.slice(0, 9);
934 strictEqual(z.length, 9);
935 }
936 
937 {
938 const z = x.slice(1, 4);
939 strictEqual(z.length, 3);
940 strictEqual(z[0], 0xa3);
941 }
942 
943 {
944 const z = x.slice(2, 4);
945 strictEqual(z.length, 2);
946 strictEqual(z[0], 0x66);
947 strictEqual(z[1], 0x6f);
948 }
949 },
950};
951 
952export const writing = {
953 test(ctrl, env, ctx) {
954 ['ucs2', 'ucs-2', 'utf16le', 'utf-16le'].forEach((encoding) => {
955 const b = Buffer.allocUnsafe(10);
956 b.write('あいうえお', encoding);
957 strictEqual(b.toString(encoding), 'あいうえお');
958 });
959 
960 ['ucs2', 'ucs-2', 'utf16le', 'utf-16le'].forEach((encoding) => {
961 const b = Buffer.allocUnsafe(11);
962 b.write('あいうえお', 1, encoding);
963 strictEqual(b.toString(encoding, 1), 'あいうえお');
964 });
965 
966 {
967 // latin1 encoding should write only one byte per character.
968 const b = Buffer.from([0xde, 0xad, 0xbe, 0xef]);
969 let s = String.fromCharCode(0xffff);
970 b.write(s, 0, 'latin1');
971 strictEqual(b[0], 0xff);
972 strictEqual(b[1], 0xad);
973 strictEqual(b[2], 0xbe);
974 strictEqual(b[3], 0xef);
975 s = String.fromCharCode(0xaaee);
976 b.write(s, 0, 'latin1');
977 strictEqual(b[0], 0xee);
978 strictEqual(b[1], 0xad);
979 strictEqual(b[2], 0xbe);
980 strictEqual(b[3], 0xef);
981 }
982 
983 {
984 // Binary encoding should write only one byte per character.
985 const b = Buffer.from([0xde, 0xad, 0xbe, 0xef]);
986 let s = String.fromCharCode(0xffff);
987 b.write(s, 0, 'latin1');
988 strictEqual(b[0], 0xff);
989 strictEqual(b[1], 0xad);
990 strictEqual(b[2], 0xbe);
991 strictEqual(b[3], 0xef);
992 s = String.fromCharCode(0xaaee);
993 b.write(s, 0, 'latin1');
994 strictEqual(b[0], 0xee);
995 strictEqual(b[1], 0xad);
996 strictEqual(b[2], 0xbe);
997 strictEqual(b[3], 0xef);
998 }
999 
1000 {
1001 const buf = Buffer.allocUnsafe(2);
1002 strictEqual(buf.write(''), 0); // 0bytes
1003 strictEqual(buf.write('\0'), 1); // 1byte (v8 adds null terminator)
1004 strictEqual(buf.write('a\0'), 2); // 1byte * 2
1005 strictEqual(buf.write('あ'), 0); // 3bytes
1006 strictEqual(buf.write('\0あ'), 1); // 1byte + 3bytes
1007 strictEqual(buf.write('\0\0あ'), 2); // 1byte * 2 + 3bytes
1008 }
1009 
1010 {
1011 const buf = Buffer.allocUnsafe(10);
1012 strictEqual(buf.write('あいう'), 9); // 3bytes * 3 (v8 adds null term.)
1013 strictEqual(buf.write('あいう\0'), 10); // 3bytes * 3 + 1byte
1014 }
1015 
1016 {
1017 // https://github.com/nodejs/node-v0.x-archive/issues/243
1018 // Test write() with maxLength
1019 const buf = Buffer.allocUnsafe(4);
1020 buf.fill(0xff);
1021 strictEqual(buf.write('abcd', 1, 2, 'utf8'), 2);
1022 strictEqual(buf[0], 0xff);
1023 strictEqual(buf[1], 0x61);
1024 strictEqual(buf[2], 0x62);
1025 strictEqual(buf[3], 0xff);
1026 
1027 buf.fill(0xff);
1028 strictEqual(buf.write('abcd', 1, 4), 3);
1029 strictEqual(buf[0], 0xff);
1030 strictEqual(buf[1], 0x61);
1031 strictEqual(buf[2], 0x62);
1032 strictEqual(buf[3], 0x63);
1033 
1034 buf.fill(0xff);
1035 strictEqual(buf.write('abcd', 1, 2, 'utf8'), 2);
1036 strictEqual(buf[0], 0xff);
1037 strictEqual(buf[1], 0x61);
1038 strictEqual(buf[2], 0x62);
1039 strictEqual(buf[3], 0xff);
1040 
1041 buf.fill(0xff);
1042 strictEqual(buf.write('abcdef', 1, 2, 'hex'), 2);
1043 strictEqual(buf[0], 0xff);
1044 strictEqual(buf[1], 0xab);
1045 strictEqual(buf[2], 0xcd);
1046 strictEqual(buf[3], 0xff);
1047 
1048 ['ucs2', 'ucs-2', 'utf16le', 'utf-16le'].forEach((encoding) => {
1049 buf.fill(0xff);
1050 strictEqual(buf.write('abcd', 0, 2, encoding), 2);
1051 strictEqual(buf[0], 0x61);
1052 strictEqual(buf[1], 0x00);
1053 strictEqual(buf[2], 0xff);
1054 strictEqual(buf[3], 0xff);
1055 });
1056 }
1057 
1058 {
1059 // Test offset returns are correct
1060 const b = Buffer.allocUnsafe(16);
1061 strictEqual(b.writeUInt32LE(0, 0), 4);
1062 strictEqual(b.writeUInt16LE(0, 4), 6);
1063 strictEqual(b.writeUInt8(0, 6), 7);
1064 strictEqual(b.writeInt8(0, 7), 8);
1065 strictEqual(b.writeDoubleLE(0, 8), 16);
1066 }
1067 
1068 {
1069 // Test for buffer overrun
1070 const buf = Buffer.from([0, 0, 0, 0, 0]); // length: 5
1071 const sub = buf.slice(0, 4); // length: 4
1072 strictEqual(sub.write('12345', 'latin1'), 4);
1073 strictEqual(buf[4], 0);
1074 strictEqual(sub.write('12345', 'binary'), 4);
1075 strictEqual(buf[4], 0);
1076 }
1077 
1078 // Test for common write(U)IntLE/BE
1079 {
1080 let buf = Buffer.allocUnsafe(3);
1081 buf.writeUIntLE(0x123456, 0, 3);
1082 deepStrictEqual(buf.toJSON().data, [0x56, 0x34, 0x12]);
1083 strictEqual(buf.readUIntLE(0, 3), 0x123456);
1084 
1085 buf.fill(0xff);
1086 buf.writeUIntBE(0x123456, 0, 3);
1087 deepStrictEqual(buf.toJSON().data, [0x12, 0x34, 0x56]);
1088 strictEqual(buf.readUIntBE(0, 3), 0x123456);
1089 
1090 buf.fill(0xff);
1091 buf.writeIntLE(0x123456, 0, 3);
1092 deepStrictEqual(buf.toJSON().data, [0x56, 0x34, 0x12]);
1093 strictEqual(buf.readIntLE(0, 3), 0x123456);
1094 
1095 buf.fill(0xff);
1096 buf.writeIntBE(0x123456, 0, 3);
1097 deepStrictEqual(buf.toJSON().data, [0x12, 0x34, 0x56]);
1098 strictEqual(buf.readIntBE(0, 3), 0x123456);
1099 
1100 buf.fill(0xff);
1101 buf.writeIntLE(-0x123456, 0, 3);
1102 deepStrictEqual(buf.toJSON().data, [0xaa, 0xcb, 0xed]);
1103 strictEqual(buf.readIntLE(0, 3), -0x123456);
1104 
1105 buf.fill(0xff);
1106 buf.writeIntBE(-0x123456, 0, 3);
1107 deepStrictEqual(buf.toJSON().data, [0xed, 0xcb, 0xaa]);
1108 strictEqual(buf.readIntBE(0, 3), -0x123456);
1109 
1110 buf.fill(0xff);
1111 buf.writeIntLE(-0x123400, 0, 3);
1112 deepStrictEqual(buf.toJSON().data, [0x00, 0xcc, 0xed]);
1113 strictEqual(buf.readIntLE(0, 3), -0x123400);
1114 
1115 buf.fill(0xff);
1116 buf.writeIntBE(-0x123400, 0, 3);
1117 deepStrictEqual(buf.toJSON().data, [0xed, 0xcc, 0x00]);
1118 strictEqual(buf.readIntBE(0, 3), -0x123400);
1119 
1120 buf.fill(0xff);
1121 buf.writeIntLE(-0x120000, 0, 3);
1122 deepStrictEqual(buf.toJSON().data, [0x00, 0x00, 0xee]);
1123 strictEqual(buf.readIntLE(0, 3), -0x120000);
1124 
1125 buf.fill(0xff);
1126 buf.writeIntBE(-0x120000, 0, 3);
1127 deepStrictEqual(buf.toJSON().data, [0xee, 0x00, 0x00]);
1128 strictEqual(buf.readIntBE(0, 3), -0x120000);
1129 
1130 buf = Buffer.allocUnsafe(5);
1131 buf.writeUIntLE(0x1234567890, 0, 5);
1132 deepStrictEqual(buf.toJSON().data, [0x90, 0x78, 0x56, 0x34, 0x12]);
1133 strictEqual(buf.readUIntLE(0, 5), 0x1234567890);
1134 
1135 buf.fill(0xff);
1136 buf.writeUIntBE(0x1234567890, 0, 5);
1137 deepStrictEqual(buf.toJSON().data, [0x12, 0x34, 0x56, 0x78, 0x90]);
1138 strictEqual(buf.readUIntBE(0, 5), 0x1234567890);
1139 
1140 buf.fill(0xff);
1141 buf.writeIntLE(0x1234567890, 0, 5);
1142 deepStrictEqual(buf.toJSON().data, [0x90, 0x78, 0x56, 0x34, 0x12]);
1143 strictEqual(buf.readIntLE(0, 5), 0x1234567890);
1144 
1145 buf.fill(0xff);
1146 buf.writeIntBE(0x1234567890, 0, 5);
1147 deepStrictEqual(buf.toJSON().data, [0x12, 0x34, 0x56, 0x78, 0x90]);
1148 strictEqual(buf.readIntBE(0, 5), 0x1234567890);
1149 
1150 buf.fill(0xff);
1151 buf.writeIntLE(-0x1234567890, 0, 5);
1152 deepStrictEqual(buf.toJSON().data, [0x70, 0x87, 0xa9, 0xcb, 0xed]);
1153 strictEqual(buf.readIntLE(0, 5), -0x1234567890);
1154 
1155 buf.fill(0xff);
1156 buf.writeIntBE(-0x1234567890, 0, 5);
1157 deepStrictEqual(buf.toJSON().data, [0xed, 0xcb, 0xa9, 0x87, 0x70]);
1158 strictEqual(buf.readIntBE(0, 5), -0x1234567890);
1159 
1160 buf.fill(0xff);
1161 buf.writeIntLE(-0x0012000000, 0, 5);
1162 deepStrictEqual(buf.toJSON().data, [0x00, 0x00, 0x00, 0xee, 0xff]);
1163 strictEqual(buf.readIntLE(0, 5), -0x0012000000);
1164 
1165 buf.fill(0xff);
1166 buf.writeIntBE(-0x0012000000, 0, 5);
1167 deepStrictEqual(buf.toJSON().data, [0xff, 0xee, 0x00, 0x00, 0x00]);
1168 strictEqual(buf.readIntBE(0, 5), -0x0012000000);
1169 }
1170 },
1171};
1172 
1173export const misc = {
1174 test(ctrl, env, ctx) {
1175 {
1176 // https://github.com/nodejs/node-v0.x-archive/pull/1210
1177 // Test UTF-8 string includes null character
1178 let buf = Buffer.from('\0');
1179 strictEqual(buf.length, 1);
1180 buf = Buffer.from('\0\0');
1181 strictEqual(buf.length, 2);
1182 }
1183 
1184 {
1185 // Test unmatched surrogates not producing invalid utf8 output
1186 // ef bf bd = utf-8 representation of unicode replacement character
1187 // see https://codereview.chromium.org/121173009/
1188 const buf = Buffer.from('ab\ud800cd', 'utf8');
1189 strictEqual(buf[0], 0x61);
1190 strictEqual(buf[1], 0x62);
1191 strictEqual(buf[2], 0xef);
1192 strictEqual(buf[3], 0xbf);
1193 strictEqual(buf[4], 0xbd);
1194 strictEqual(buf[5], 0x63);
1195 strictEqual(buf[6], 0x64);
1196 }
1197 
1198 {
1199 // Test alloc with fill option
1200 const buf = Buffer.alloc(5, '800A', 'hex');
1201 strictEqual(buf[0], 128);
1202 strictEqual(buf[1], 10);
1203 strictEqual(buf[2], 128);
1204 strictEqual(buf[3], 10);
1205 strictEqual(buf[4], 128);
1206 }
1207 
1208 // Call .fill() first, stops Valgrind warning about uninitialized memory reads.
1209 Buffer.allocUnsafe(3.3).fill().toString();
1210 // Throws bad argument error in commit 43cb4ec
1211 Buffer.alloc(3.3).fill().toString();
1212 strictEqual(Buffer.allocUnsafe(3.3).length, 3);
1213 strictEqual(Buffer.from({ length: 3.3 }).length, 3);
1214 strictEqual(Buffer.from({ length: 'BAM' }).length, 0);
1215 
1216 strictEqual(Buffer.from('99').length, 2);
1217 strictEqual(Buffer.from('13.37').length, 5);
1218 
1219 // Ensure that the length argument is respected.
1220 ['ascii', 'utf8', 'hex', 'base64', 'latin1', 'binary'].forEach((enc) => {
1221 strictEqual(Buffer.allocUnsafe(1).write('aaaaaa', 0, 1, enc), 1);
1222 });
1223 
1224 {
1225 // Regression test, guard against buffer overrun in the base64 decoder.
1226 const a = Buffer.allocUnsafe(3);
1227 const b = Buffer.from('xxx');
1228 a.write('aaaaaaaa', 'base64');
1229 strictEqual(b.toString(), 'xxx');
1230 }
1231 
1232 // issue GH-3416
1233 Buffer.from(Buffer.allocUnsafe(0), 0, 0);
1234 
1235 const outOfRangeError = {
1236 code: 'ERR_OUT_OF_RANGE',
1237 name: 'RangeError',
1238 };
1239 
1240 // issue GH-5587
1241 throws(() => Buffer.alloc(8).writeFloatLE(0, 5), outOfRangeError);
1242 throws(() => Buffer.alloc(16).writeDoubleLE(0, 9), outOfRangeError);
1243 
1244 // Attempt to overflow buffers, similar to previous bug in array buffers
1245 throws(
1246 () => Buffer.allocUnsafe(8).writeFloatLE(0.0, 0xffffffff),
1247 outOfRangeError
1248 );
1249 throws(
1250 () => Buffer.allocUnsafe(8).writeFloatLE(0.0, 0xffffffff),
1251 outOfRangeError
1252 );
1253 
1254 // Ensure negative values can't get past offset
1255 throws(() => Buffer.allocUnsafe(8).writeFloatLE(0.0, -1), outOfRangeError);
1256 throws(() => Buffer.allocUnsafe(8).writeFloatLE(0.0, -1), outOfRangeError);
1257 
1258 // Regression test for https://github.com/nodejs/node-v0.x-archive/issues/5482:
1259 // should throw but not assert in C++ land.
1260 throws(() => Buffer.from('', 'buffer'), {
1261 code: 'ERR_UNKNOWN_ENCODING',
1262 name: 'TypeError',
1263 message: 'Unknown encoding: buffer',
1264 });
1265 
1266 // Regression test for https://github.com/nodejs/node-v0.x-archive/issues/6111.
1267 // Constructing a buffer from another buffer should a) work, and b) not corrupt
1268 // the source buffer.
1269 {
1270 const a = [...Array(128).keys()]; // [0, 1, 2, 3, ... 126, 127]
1271 const b = Buffer.from(a);
1272 const c = Buffer.from(b);
1273 strictEqual(b.length, a.length);
1274 strictEqual(c.length, a.length);
1275 for (let i = 0, k = a.length; i < k; ++i) {
1276 strictEqual(a[i], i);
1277 strictEqual(b[i], i);
1278 strictEqual(c[i], i);
1279 }
1280 }
1281 
1282 throws(() => Buffer.allocUnsafe(10).copy(), {
1283 code: 'ERR_INVALID_ARG_TYPE',
1284 name: 'TypeError',
1285 message:
1286 'The "target" argument must be an instance of Buffer or ' +
1287 'Uint8Array. Received undefined',
1288 });
1289 
1290 throws(() => Buffer.from(), {
1291 name: 'TypeError',
1292 });
1293 throws(() => Buffer.from(null), {
1294 name: 'TypeError',
1295 });
1296 
1297 // Test prototype getters don't throw
1298 strictEqual(Buffer.prototype.parent, undefined);
1299 strictEqual(Buffer.prototype.offset, undefined);
1300 strictEqual(SlowBuffer.prototype.parent, undefined);
1301 strictEqual(SlowBuffer.prototype.offset, undefined);
1302 
1303 {
1304 // Test that large negative Buffer length inputs don't affect the pool offset.
1305 // Use the fromArrayLike() variant here because it's more lenient
1306 // about its input and passes the length directly to allocate().
1307 deepStrictEqual(Buffer.from({ length: -3456 }), Buffer.from(''));
1308 deepStrictEqual(Buffer.from({ length: -100 }), Buffer.from(''));
1309 
1310 // Check pool offset after that by trying to write string into the pool.
1311 Buffer.from('abc');
1312 }
1313 
1314 // Test that ParseArrayIndex handles full uint32
1315 {
1316 throws(() => Buffer.from(new ArrayBuffer(0), -1 >>> 0), {
1317 code: 'ERR_BUFFER_OUT_OF_BOUNDS',
1318 name: 'RangeError',
1319 message: '"offset" is outside of buffer bounds',
1320 });
1321 }
1322 
1323 // ParseArrayIndex() should reject values that don't fit in a 32 bits size_t.
1324 throws(() => {
1325 const a = Buffer.alloc(1);
1326 const b = Buffer.alloc(1);
1327 a.copy(b, 0, 0x100000000, 0x100000001);
1328 }, outOfRangeError);
1329 
1330 // Unpooled buffer (replaces SlowBuffer)
1331 {
1332 const ubuf = Buffer.allocUnsafeSlow(10);
1333 ok(ubuf);
1334 ok(ubuf.buffer);
1335 strictEqual(ubuf.buffer.byteLength, 10);
1336 }
1337 
1338 // Regression test to verify that an empty ArrayBuffer does not throw.
1339 Buffer.from(new ArrayBuffer());
1340 
1341 throws(
1342 () => Buffer.alloc({ valueOf: () => 1 }),
1343 /"size" argument must be of type number/
1344 );
1345 throws(
1346 () => Buffer.alloc({ valueOf: () => -1 }),
1347 /"size" argument must be of type number/
1348 );
1349 
1350 strictEqual(Buffer.prototype.toLocaleString, Buffer.prototype.toString);
1351 {
1352 const buf = Buffer.from('test');
1353 strictEqual(buf.toLocaleString(), buf.toString());
1354 }
1355 
1356 throws(
1357 () => {
1358 Buffer.alloc(0x1000, 'This is not correctly encoded', 'hex');
1359 },
1360 {
1361 name: 'TypeError',
1362 }
1363 );
1364 
1365 throws(
1366 () => {
1367 Buffer.alloc(0x1000, 'c', 'hex');
1368 },
1369 {
1370 name: 'TypeError',
1371 }
1372 );
1373 
1374 throws(
1375 () => {
1376 Buffer.alloc(1, Buffer.alloc(0));
1377 },
1378 {
1379 code: 'ERR_INVALID_ARG_VALUE',
1380 name: 'TypeError',
1381 }
1382 );
1383 
1384 throws(
1385 () => {
1386 Buffer.alloc(40, 'x', 20);
1387 },
1388 {
1389 code: 'ERR_INVALID_ARG_TYPE',
1390 name: 'TypeError',
1391 }
1392 );
1393 },
1394};
1395 
1396export const arrayBuffers = {
1397 test(ctrl, env, ctx) {
1398 const LENGTH = 16;
1399 
1400 const ab = new ArrayBuffer(LENGTH);
1401 const dv = new DataView(ab);
1402 const ui = new Uint8Array(ab);
1403 const buf = Buffer.from(ab);
1404 
1405 ok(buf instanceof Buffer);
1406 strictEqual(buf.parent, buf.buffer);
1407 strictEqual(buf.buffer, ab);
1408 strictEqual(buf.length, ab.byteLength);
1409 
1410 buf.fill(0xc);
1411 for (let i = 0; i < LENGTH; i++) {
1412 strictEqual(ui[i], 0xc);
1413 ui[i] = 0xf;
1414 strictEqual(buf[i], 0xf);
1415 }
1416 
1417 buf.writeUInt32LE(0xf00, 0);
1418 buf.writeUInt32BE(0xb47, 4);
1419 buf.writeDoubleLE(3.1415, 8);
1420 
1421 strictEqual(dv.getUint32(0, true), 0xf00);
1422 strictEqual(dv.getUint32(4), 0xb47);
1423 strictEqual(dv.getFloat64(8, true), 3.1415);
1424 
1425 // Now test protecting users from doing stupid things
1426 
1427 throws(
1428 function () {
1429 function AB() {}
1430 Object.setPrototypeOf(AB, ArrayBuffer);
1431 Object.setPrototypeOf(AB.prototype, ArrayBuffer.prototype);
1432 Buffer.from(new AB());
1433 },
1434 {
1435 name: 'TypeError',
1436 }
1437 );
1438 
1439 // Test the byteOffset and length arguments
1440 {
1441 const ab = new Uint8Array(5);
1442 ab[0] = 1;
1443 ab[1] = 2;
1444 ab[2] = 3;
1445 ab[3] = 4;
1446 ab[4] = 5;
1447 const buf = Buffer.from(ab.buffer, 1, 3);
1448 strictEqual(buf.length, 3);
1449 strictEqual(buf[0], 2);
1450 strictEqual(buf[1], 3);
1451 strictEqual(buf[2], 4);
1452 buf[0] = 9;
1453 strictEqual(ab[1], 9);
1454 
1455 throws(() => Buffer.from(ab.buffer, 6), {
1456 code: 'ERR_BUFFER_OUT_OF_BOUNDS',
1457 name: 'RangeError',
1458 message: '"offset" is outside of buffer bounds',
1459 });
1460 throws(() => Buffer.from(ab.buffer, 3, 6), {
1461 code: 'ERR_BUFFER_OUT_OF_BOUNDS',
1462 name: 'RangeError',
1463 message: '"length" is outside of buffer bounds',
1464 });
1465 }
1466 
1467 // Test the deprecated Buffer() version also
1468 {
1469 const ab = new Uint8Array(5);
1470 ab[0] = 1;
1471 ab[1] = 2;
1472 ab[2] = 3;
1473 ab[3] = 4;
1474 ab[4] = 5;
1475 const buf = Buffer(ab.buffer, 1, 3);
1476 strictEqual(buf.length, 3);
1477 strictEqual(buf[0], 2);
1478 strictEqual(buf[1], 3);
1479 strictEqual(buf[2], 4);
1480 buf[0] = 9;
1481 strictEqual(ab[1], 9);
1482 
1483 throws(() => Buffer(ab.buffer, 6), {
1484 code: 'ERR_BUFFER_OUT_OF_BOUNDS',
1485 name: 'RangeError',
1486 message: '"offset" is outside of buffer bounds',
1487 });
1488 throws(() => Buffer(ab.buffer, 3, 6), {
1489 code: 'ERR_BUFFER_OUT_OF_BOUNDS',
1490 name: 'RangeError',
1491 message: '"length" is outside of buffer bounds',
1492 });
1493 }
1494 
1495 {
1496 // If byteOffset is not numeric, it defaults to 0.
1497 const ab = new ArrayBuffer(10);
1498 const expected = Buffer.from(ab, 0);
1499 deepStrictEqual(Buffer.from(ab, 'fhqwhgads'), expected);
1500 deepStrictEqual(Buffer.from(ab, NaN), expected);
1501 deepStrictEqual(Buffer.from(ab, {}), expected);
1502 deepStrictEqual(Buffer.from(ab, []), expected);
1503 
1504 // If byteOffset can be converted to a number, it will be.
1505 deepStrictEqual(Buffer.from(ab, [1]), Buffer.from(ab, 1));
1506 
1507 // If byteOffset is Infinity, throw.
1508 throws(
1509 () => {
1510 Buffer.from(ab, Infinity);
1511 },
1512 {
1513 code: 'ERR_BUFFER_OUT_OF_BOUNDS',
1514 name: 'RangeError',
1515 message: '"offset" is outside of buffer bounds',
1516 }
1517 );
1518 }
1519 
1520 {
1521 // If length is not numeric, it defaults to 0.
1522 const ab = new ArrayBuffer(10);
1523 const expected = Buffer.from(ab, 0, 0);
1524 deepStrictEqual(Buffer.from(ab, 0, 'fhqwhgads'), expected);
1525 deepStrictEqual(Buffer.from(ab, 0, NaN), expected);
1526 deepStrictEqual(Buffer.from(ab, 0, {}), expected);
1527 deepStrictEqual(Buffer.from(ab, 0, []), expected);
1528 
1529 // If length can be converted to a number, it will be.
1530 deepStrictEqual(Buffer.from(ab, 0, [1]), Buffer.from(ab, 0, 1));
1531 
1532 // If length is Infinity, throw.
1533 throws(
1534 () => {
1535 Buffer.from(ab, 0, Infinity);
1536 },
1537 {
1538 code: 'ERR_BUFFER_OUT_OF_BOUNDS',
1539 name: 'RangeError',
1540 message: '"length" is outside of buffer bounds',
1541 }
1542 );
1543 }
1544 
1545 // Test an array like entry with the length set to NaN.
1546 deepStrictEqual(Buffer.from({ length: NaN }), Buffer.alloc(0));
1547 },
1548};
1549 
1550export const ascii = {
1551 test(ctrl, env, ctx) {
1552 // ASCII conversion in node.js simply masks off the high bits,
1553 // it doesn't do transliteration.
1554 strictEqual(Buffer.from('hérité').toString('ascii'), 'hC)ritC)');
1555 // 71 characters, 78 bytes. The ’ character is a triple-byte sequence.
1556 const input =
1557 'C’est, graphiquement, la réunion d’un accent aigu ' +
1558 'et d’un accent grave.';
1559 
1560 const expected =
1561 'Cb\u0000\u0019est, graphiquement, la rC)union ' +
1562 'db\u0000\u0019un accent aigu et db\u0000\u0019un ' +
1563 'accent grave.';
1564 
1565 const buf = Buffer.from(input);
1566 
1567 for (let i = 0; i < expected.length; ++i) {
1568 strictEqual(buf.slice(i).toString('ascii'), expected.slice(i));
1569 
1570 // Skip remainder of multi-byte sequence.
1571 if (input.charCodeAt(i) > 65535) ++i;
1572 if (input.charCodeAt(i) > 127) ++i;
1573 }
1574 },
1575};
1576 
1577export const badHex = {
1578 test(ctrl, env, ctx) {
1579 // Test hex strings and bad hex strings
1580 {
1581 const buf = Buffer.alloc(4);
1582 strictEqual(buf.length, 4);
1583 deepStrictEqual(buf, Buffer.from([0, 0, 0, 0]));
1584 strictEqual(buf.write('abcdxx', 0, 'hex'), 2);
1585 deepStrictEqual(buf, Buffer.from([0xab, 0xcd, 0x00, 0x00]));
1586 strictEqual(buf.toString('hex'), 'abcd0000');
1587 strictEqual(buf.write('abcdef01', 0, 'hex'), 4);
1588 deepStrictEqual(buf, Buffer.from([0xab, 0xcd, 0xef, 0x01]));
1589 strictEqual(buf.toString('hex'), 'abcdef01');
1590 
1591 const copy = Buffer.from(buf.toString('hex'), 'hex');
1592 strictEqual(buf.toString('hex'), copy.toString('hex'));
1593 }
1594 
1595 {
1596 const buf = Buffer.alloc(5);
1597 strictEqual(buf.write('abcdxx', 1, 'hex'), 2);
1598 strictEqual(buf.toString('hex'), '00abcd0000');
1599 }
1600 
1601 {
1602 const buf = Buffer.alloc(4);
1603 deepStrictEqual(buf, Buffer.from([0, 0, 0, 0]));
1604 strictEqual(buf.write('xxabcd', 0, 'hex'), 0);
1605 deepStrictEqual(buf, Buffer.from([0, 0, 0, 0]));
1606 strictEqual(buf.write('xxab', 1, 'hex'), 0);
1607 deepStrictEqual(buf, Buffer.from([0, 0, 0, 0]));
1608 strictEqual(buf.write('cdxxab', 0, 'hex'), 1);
1609 deepStrictEqual(buf, Buffer.from([0xcd, 0, 0, 0]));
1610 }
1611 
1612 {
1613 const buf = Buffer.alloc(256);
1614 for (let i = 0; i < 256; i++) buf[i] = i;
1615 
1616 const hex = buf.toString('hex');
1617 deepStrictEqual(Buffer.from(hex, 'hex'), buf);
1618 
1619 const badHex = `${hex.slice(0, 256)}xx${hex.slice(256, 510)}`;
1620 deepStrictEqual(Buffer.from(badHex, 'hex'), buf.slice(0, 128));
1621 }
1622 },
1623};
1624 
1625export const bigint64 = {
1626 test(ctrl, env, ctx) {
1627 const buf = Buffer.allocUnsafe(8);
1628 
1629 ['LE', 'BE'].forEach(function (endianness) {
1630 // Should allow simple BigInts to be written and read
1631 let val = 123456789n;
1632 buf[`writeBigInt64${endianness}`](val, 0);
1633 let rtn = buf[`readBigInt64${endianness}`](0);
1634 strictEqual(val, rtn);
1635 
1636 // Should allow INT64_MAX to be written and read
1637 val = 0x7fffffffffffffffn;
1638 buf[`writeBigInt64${endianness}`](val, 0);
1639 rtn = buf[`readBigInt64${endianness}`](0);
1640 strictEqual(val, rtn);
1641 
1642 // Should read and write a negative signed 64-bit integer
1643 val = -123456789n;
1644 buf[`writeBigInt64${endianness}`](val, 0);
1645 strictEqual(val, buf[`readBigInt64${endianness}`](0));
1646 
1647 // Should read and write an unsigned 64-bit integer
1648 val = 123456789n;
1649 buf[`writeBigUInt64${endianness}`](val, 0);
1650 strictEqual(val, buf[`readBigUInt64${endianness}`](0));
1651 
1652 // Should throw a RangeError upon INT64_MAX+1 being written
1653 throws(function () {
1654 const val = 0x8000000000000000n;
1655 buf[`writeBigInt64${endianness}`](val, 0);
1656 }, RangeError);
1657 
1658 // Should throw a RangeError upon UINT64_MAX+1 being written
1659 throws(
1660 function () {
1661 const val = 0x10000000000000000n;
1662 buf[`writeBigUInt64${endianness}`](val, 0);
1663 },
1664 {
1665 code: 'ERR_OUT_OF_RANGE',
1666 message:
1667 'The value of "value" is out of range. It must be ' +
1668 '>= 0n and < 2n ** 64n. Received 18_446_744_073_709_551_616n',
1669 }
1670 );
1671 
1672 // Should throw a TypeError upon invalid input
1673 throws(function () {
1674 buf[`writeBigInt64${endianness}`]('bad', 0);
1675 }, TypeError);
1676 
1677 // Should throw a TypeError upon invalid input
1678 throws(function () {
1679 buf[`writeBigUInt64${endianness}`]('bad', 0);
1680 }, TypeError);
1681 });
1682 },
1683};
1684 
1685export const byteLength = {
1686 test(ctrl, env, ctx) {
1687 [[32, 'latin1'], [NaN, 'utf8'], [{}, 'latin1'], []].forEach((args) => {
1688 throws(() => Buffer.byteLength(...args), {
1689 code: 'ERR_INVALID_ARG_TYPE',
1690 name: 'TypeError',
1691 });
1692 });
1693 
1694 ok(ArrayBuffer.isView(new Buffer(10)));
1695 ok(ArrayBuffer.isView(new SlowBuffer(10)));
1696 ok(ArrayBuffer.isView(Buffer.alloc(10)));
1697 ok(ArrayBuffer.isView(Buffer.allocUnsafe(10)));
1698 ok(ArrayBuffer.isView(Buffer.allocUnsafeSlow(10)));
1699 ok(ArrayBuffer.isView(Buffer.from('')));
1700 
1701 // buffer
1702 const incomplete = Buffer.from([0xe4, 0xb8, 0xad, 0xe6, 0x96]);
1703 strictEqual(Buffer.byteLength(incomplete), 5);
1704 const ascii = Buffer.from('abc');
1705 strictEqual(Buffer.byteLength(ascii), 3);
1706 
1707 // ArrayBuffer
1708 const buffer = new ArrayBuffer(8);
1709 strictEqual(Buffer.byteLength(buffer), 8);
1710 
1711 // TypedArray
1712 const int8 = new Int8Array(8);
1713 strictEqual(Buffer.byteLength(int8), 8);
1714 const uint8 = new Uint8Array(8);
1715 strictEqual(Buffer.byteLength(uint8), 8);
1716 const uintc8 = new Uint8ClampedArray(2);
1717 strictEqual(Buffer.byteLength(uintc8), 2);
1718 const int16 = new Int16Array(8);
1719 strictEqual(Buffer.byteLength(int16), 16);
1720 const uint16 = new Uint16Array(8);
1721 strictEqual(Buffer.byteLength(uint16), 16);
1722 const int32 = new Int32Array(8);
1723 strictEqual(Buffer.byteLength(int32), 32);
1724 const uint32 = new Uint32Array(8);
1725 strictEqual(Buffer.byteLength(uint32), 32);
1726 const float16 = new Float16Array(8);
1727 strictEqual(Buffer.byteLength(float16), 16);
1728 const float32 = new Float32Array(8);
1729 strictEqual(Buffer.byteLength(float32), 32);
1730 const float64 = new Float64Array(8);
1731 strictEqual(Buffer.byteLength(float64), 64);
1732 
1733 // DataView
1734 const dv = new DataView(new ArrayBuffer(2));
1735 strictEqual(Buffer.byteLength(dv), 2);
1736 
1737 // Special case: zero length string
1738 strictEqual(Buffer.byteLength('', 'ascii'), 0);
1739 strictEqual(Buffer.byteLength('', 'HeX'), 0);
1740 
1741 // utf8
1742 strictEqual(Buffer.byteLength('∑éllö wørl∂!', 'utf-8'), 19);
1743 strictEqual(Buffer.byteLength('κλμνξο', 'utf8'), 12);
1744 strictEqual(Buffer.byteLength('挵挶挷挸挹', 'utf-8'), 15);
1745 strictEqual(Buffer.byteLength('𠝹𠱓𠱸', 'UTF8'), 12);
1746 // Without an encoding, utf8 should be assumed
1747 strictEqual(Buffer.byteLength('hey there'), 9);
1748 strictEqual(Buffer.byteLength('𠱸挶νξ#xx :)'), 17);
1749 strictEqual(Buffer.byteLength('hello world', ''), 11);
1750 // It should also be assumed with unrecognized encoding
1751 
1752 strictEqual(Buffer.byteLength('hello world', 'abc'), 11);
1753 strictEqual(Buffer.byteLength('ßœ∑≈', 'unkn0wn enc0ding'), 10);
1754 
1755 // base64
1756 strictEqual(Buffer.byteLength('aGVsbG8gd29ybGQ=', 'base64'), 11);
1757 strictEqual(Buffer.byteLength('aGVsbG8gd29ybGQ=', 'BASE64'), 11);
1758 strictEqual(Buffer.byteLength('bm9kZS5qcyByb2NrcyE=', 'base64'), 14);
1759 strictEqual(Buffer.byteLength('aGkk', 'base64'), 3);
1760 strictEqual(
1761 Buffer.byteLength('bHNrZGZsa3NqZmtsc2xrZmFqc2RsZmtqcw==', 'base64'),
1762 25
1763 );
1764 // base64url
1765 strictEqual(Buffer.byteLength('aGVsbG8gd29ybGQ', 'base64url'), 11);
1766 strictEqual(Buffer.byteLength('aGVsbG8gd29ybGQ', 'BASE64URL'), 11);
1767 strictEqual(Buffer.byteLength('bm9kZS5qcyByb2NrcyE', 'base64url'), 14);
1768 strictEqual(Buffer.byteLength('aGkk', 'base64url'), 3);
1769 strictEqual(
1770 Buffer.byteLength('bHNrZGZsa3NqZmtsc2xrZmFqc2RsZmtqcw', 'base64url'),
1771 25
1772 );
1773 // special padding
1774 strictEqual(Buffer.byteLength('aaa=', 'base64'), 2);
1775 strictEqual(Buffer.byteLength('aaaa==', 'base64'), 3);
1776 strictEqual(Buffer.byteLength('aaa=', 'base64url'), 2);
1777 strictEqual(Buffer.byteLength('aaaa==', 'base64url'), 3);
1778 
1779 strictEqual(Buffer.byteLength('Il était tué'), 14);
1780 strictEqual(Buffer.byteLength('Il était tué', 'utf8'), 14);
1781 
1782 ['ascii', 'latin1', 'binary']
1783 .reduce((es, e) => es.concat(e, e.toUpperCase()), [])
1784 .forEach((encoding) => {
1785 strictEqual(Buffer.byteLength('Il était tué', encoding), 12);
1786 });
1787 
1788 ['ucs2', 'ucs-2', 'utf16le', 'utf-16le']
1789 .reduce((es, e) => es.concat(e, e.toUpperCase()), [])
1790 .forEach((encoding) => {
1791 strictEqual(Buffer.byteLength('Il était tué', encoding), 24);
1792 });
1793 
1794 // Verify that invalid encodings are treated as utf8
1795 for (let i = 1; i < 10; i++) {
1796 const encoding = String(i).repeat(i);
1797 
1798 ok(!Buffer.isEncoding(encoding));
1799 strictEqual(
1800 Buffer.byteLength('foo', encoding),
1801 Buffer.byteLength('foo', 'utf8')
1802 );
1803 }
1804 },
1805};
1806 
1807export const compareOffset = {
1808 test(ctrl, env, ctx) {
1809 const a = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
1810 const b = Buffer.from([5, 6, 7, 8, 9, 0, 1, 2, 3, 4]);
1811 
1812 strictEqual(a.compare(b), -1);
1813 
1814 // Equivalent to a.compare(b).
1815 strictEqual(a.compare(b, 0), -1);
1816 throws(() => a.compare(b, '0'), { code: 'ERR_INVALID_ARG_TYPE' });
1817 strictEqual(a.compare(b, undefined), -1);
1818 
1819 // Equivalent to a.compare(b).
1820 strictEqual(a.compare(b, 0, undefined, 0), -1);
1821 
1822 // Zero-length target, return 1
1823 strictEqual(a.compare(b, 0, 0, 0), 1);
1824 throws(() => a.compare(b, 0, '0', '0'), { code: 'ERR_INVALID_ARG_TYPE' });
1825 
1826 // Equivalent to Buffer.compare(a, b.slice(6, 10))
1827 strictEqual(a.compare(b, 6, 10), 1);
1828 
1829 // Zero-length source, return -1
1830 strictEqual(a.compare(b, 6, 10, 0, 0), -1);
1831 
1832 // Zero-length source and target, return 0
1833 strictEqual(a.compare(b, 0, 0, 0, 0), 0);
1834 strictEqual(a.compare(b, 1, 1, 2, 2), 0);
1835 
1836 // Equivalent to Buffer.compare(a.slice(4), b.slice(0, 5))
1837 strictEqual(a.compare(b, 0, 5, 4), 1);
1838 
1839 // Equivalent to Buffer.compare(a.slice(1), b.slice(5))
1840 strictEqual(a.compare(b, 5, undefined, 1), 1);
1841 
1842 // Equivalent to Buffer.compare(a.slice(2), b.slice(2, 4))
1843 strictEqual(a.compare(b, 2, 4, 2), -1);
1844 
1845 // Equivalent to Buffer.compare(a.slice(4), b.slice(0, 7))
1846 strictEqual(a.compare(b, 0, 7, 4), -1);
1847 
1848 // Equivalent to Buffer.compare(a.slice(4, 6), b.slice(0, 7));
1849 strictEqual(a.compare(b, 0, 7, 4, 6), -1);
1850 
1851 // Null is ambiguous.
1852 throws(() => a.compare(b, 0, null), { code: 'ERR_INVALID_ARG_TYPE' });
1853 
1854 // Values do not get coerced.
1855 throws(() => a.compare(b, 0, { valueOf: () => 5 }), {
1856 code: 'ERR_INVALID_ARG_TYPE',
1857 });
1858 
1859 // Infinity should not be coerced.
1860 throws(() => a.compare(b, Infinity, -Infinity), {
1861 code: 'ERR_OUT_OF_RANGE',
1862 });
1863 
1864 // Zero length target because default for targetEnd <= targetSource
1865 strictEqual(a.compare(b, 0xff), 1);
1866 
1867 throws(() => a.compare(b, '0xff'), { code: 'ERR_INVALID_ARG_TYPE' });
1868 throws(() => a.compare(b, 0, '0xff'), { code: 'ERR_INVALID_ARG_TYPE' });
1869 
1870 const oor = { code: 'ERR_OUT_OF_RANGE' };
1871 
1872 throws(() => a.compare(b, 0, 100, 0), oor);
1873 throws(() => a.compare(b, 0, 1, 0, 100), oor);
1874 throws(() => a.compare(b, -1), oor);
1875 throws(() => a.compare(b, 0, Infinity), oor);
1876 throws(() => a.compare(b, 0, 1, -1), oor);
1877 throws(() => a.compare(b, -Infinity, Infinity), oor);
1878 throws(() => a.compare(), {
1879 code: 'ERR_INVALID_ARG_TYPE',
1880 name: 'TypeError',
1881 message:
1882 'The "target" argument must be an instance of ' +
1883 'Buffer or Uint8Array. Received undefined',
1884 });
1885 },
1886};
1887 
1888export const compare = {
1889 test(ctrl, env, ctx) {
1890 const b = Buffer.alloc(1, 'a');
1891 const c = Buffer.alloc(1, 'c');
1892 const d = Buffer.alloc(2, 'aa');
1893 const e = new Uint8Array([0x61, 0x61]); // ASCII 'aa', same as d
1894 
1895 strictEqual(b.compare(c), -1);
1896 strictEqual(c.compare(d), 1);
1897 strictEqual(d.compare(b), 1);
1898 strictEqual(d.compare(e), 0);
1899 strictEqual(b.compare(d), -1);
1900 strictEqual(b.compare(b), 0);
1901 
1902 strictEqual(Buffer.compare(b, c), -1);
1903 strictEqual(Buffer.compare(c, d), 1);
1904 strictEqual(Buffer.compare(d, b), 1);
1905 strictEqual(Buffer.compare(b, d), -1);
1906 strictEqual(Buffer.compare(c, c), 0);
1907 strictEqual(Buffer.compare(e, e), 0);
1908 strictEqual(Buffer.compare(d, e), 0);
1909 strictEqual(Buffer.compare(d, b), 1);
1910 
1911 strictEqual(Buffer.compare(Buffer.alloc(0), Buffer.alloc(0)), 0);
1912 strictEqual(Buffer.compare(Buffer.alloc(0), Buffer.alloc(1)), -1);
1913 strictEqual(Buffer.compare(Buffer.alloc(1), Buffer.alloc(0)), 1);
1914 
1915 throws(() => Buffer.compare(Buffer.alloc(1), 'abc'), {
1916 code: 'ERR_INVALID_ARG_TYPE',
1917 });
1918 throws(() => Buffer.compare('abc', Buffer.alloc(1)), {
1919 code: 'ERR_INVALID_ARG_TYPE',
1920 });
1921 
1922 throws(() => Buffer.alloc(1).compare('abc'), {
1923 code: 'ERR_INVALID_ARG_TYPE',
1924 name: 'TypeError',
1925 });
1926 },
1927};
1928 
1929export const concat = {
1930 test(ctrl, env, ctx) {
1931 const zero = [];
1932 const one = [Buffer.from('asdf')];
1933 const long = [];
1934 for (let i = 0; i < 10; i++) long.push(Buffer.from('asdf'));
1935 
1936 const flatZero = Buffer.concat(zero);
1937 const flatOne = Buffer.concat(one);
1938 const flatLong = Buffer.concat(long);
1939 const flatLongLen = Buffer.concat(long, 40);
1940 
1941 strictEqual(flatZero.length, 0);
1942 strictEqual(flatOne.toString(), 'asdf');
1943 
1944 const check = 'asdf'.repeat(10);
1945 
1946 // A special case where concat used to return the first item,
1947 // if the length is one. This check is to make sure that we don't do that.
1948 notStrictEqual(flatOne, one[0]);
1949 strictEqual(flatLong.toString(), check);
1950 strictEqual(flatLongLen.toString(), check);
1951 
1952 [undefined, null, Buffer.from('hello')].forEach((value) => {
1953 throws(
1954 () => {
1955 Buffer.concat(value);
1956 },
1957 {
1958 name: 'TypeError',
1959 }
1960 );
1961 });
1962 
1963 [[42], ['hello', Buffer.from('world')]].forEach((value) => {
1964 throws(
1965 () => {
1966 Buffer.concat(value);
1967 },
1968 {
1969 name: 'TypeError',
1970 //code: 'ERR_INVALID_ARG_TYPE',
1971 }
1972 );
1973 });
1974 
1975 throws(
1976 () => {
1977 Buffer.concat([Buffer.from('hello'), 3]);
1978 },
1979 {
1980 name: 'TypeError',
1981 //code: 'ERR_INVALID_ARG_TYPE',
1982 }
1983 );
1984 
1985 const random10 = Buffer.alloc(10);
1986 crypto.getRandomValues(random10);
1987 const empty = Buffer.alloc(0);
1988 
1989 notDeepStrictEqual(random10, empty);
1990 notDeepStrictEqual(random10, Buffer.alloc(10));
1991 
1992 deepStrictEqual(Buffer.concat([], 100), empty);
1993 deepStrictEqual(Buffer.concat([random10], 0), empty);
1994 deepStrictEqual(Buffer.concat([random10], 10), random10);
1995 deepStrictEqual(Buffer.concat([random10, random10], 10), random10);
1996 deepStrictEqual(Buffer.concat([empty, random10]), random10);
1997 deepStrictEqual(Buffer.concat([random10, empty, empty]), random10);
1998 
1999 // The tail should be zero-filled
2000 deepStrictEqual(Buffer.concat([empty], 100), Buffer.alloc(100));
2001 deepStrictEqual(Buffer.concat([empty], 4096), Buffer.alloc(4096));
2002 deepStrictEqual(
2003 Buffer.concat([random10], 40),
2004 Buffer.concat([random10, Buffer.alloc(30)])
2005 );
2006 
2007 deepStrictEqual(
2008 Buffer.concat([
2009 new Uint8Array([0x41, 0x42]),
2010 new Uint8Array([0x43, 0x44]),
2011 ]),
2012 Buffer.from('ABCD')
2013 );
2014 },
2015};
2016 
2017export const konstants = {
2018 test(ctrl, env, ctx) {
2019 strictEqual(typeof MAX_LENGTH, 'number');
2020 strictEqual(typeof MAX_STRING_LENGTH, 'number');
2021 ok(MAX_STRING_LENGTH <= MAX_LENGTH);
2022 throws(
2023 () => ' '.repeat(MAX_STRING_LENGTH + 1),
2024 /^RangeError: Invalid string length$/
2025 );
2026 ' '.repeat(MAX_STRING_LENGTH); // Should not throw.
2027 // Legacy values match:
2028 strictEqual(kMaxLength, MAX_LENGTH);
2029 strictEqual(kStringMaxLength, MAX_STRING_LENGTH);
2030 },
2031};
2032 
2033export const copy = {
2034 test(ctrl, env, ctx) {
2035 const b = Buffer.allocUnsafe(1024);
2036 const c = Buffer.allocUnsafe(512);
2037 
2038 let cntr = 0;
2039 
2040 {
2041 // copy 512 bytes, from 0 to 512.
2042 b.fill(++cntr);
2043 c.fill(++cntr);
2044 const copied = b.copy(c, 0, 0, 512);
2045 strictEqual(copied, 512);
2046 for (let i = 0; i < c.length; i++) {
2047 strictEqual(c[i], b[i]);
2048 }
2049 }
2050 
2051 {
2052 // Current behavior is to coerce values to integers.
2053 b.fill(++cntr);
2054 c.fill(++cntr);
2055 const copied = b.copy(c, '0', '0', '512');
2056 strictEqual(copied, 512);
2057 for (let i = 0; i < c.length; i++) {
2058 strictEqual(c[i], b[i]);
2059 }
2060 }
2061 
2062 {
2063 // Floats will be converted to integers via `Math.floor`
2064 b.fill(++cntr);
2065 c.fill(++cntr);
2066 const copied = b.copy(c, 0, 0, 512.5);
2067 strictEqual(copied, 512);
2068 for (let i = 0; i < c.length; i++) {
2069 strictEqual(c[i], b[i]);
2070 }
2071 }
2072 
2073 {
2074 // Copy c into b, without specifying sourceEnd
2075 b.fill(++cntr);
2076 c.fill(++cntr);
2077 const copied = c.copy(b, 0, 0);
2078 strictEqual(copied, c.length);
2079 for (let i = 0; i < c.length; i++) {
2080 strictEqual(b[i], c[i]);
2081 }
2082 }
2083 
2084 {
2085 // Copy c into b, without specifying sourceStart
2086 b.fill(++cntr);
2087 c.fill(++cntr);
2088 const copied = c.copy(b, 0);
2089 strictEqual(copied, c.length);
2090 for (let i = 0; i < c.length; i++) {
2091 strictEqual(b[i], c[i]);
2092 }
2093 }
2094 
2095 {
2096 // Copied source range greater than source length
2097 b.fill(++cntr);
2098 c.fill(++cntr);
2099 const copied = c.copy(b, 0, 0, c.length + 1);
2100 strictEqual(copied, c.length);
2101 for (let i = 0; i < c.length; i++) {
2102 strictEqual(b[i], c[i]);
2103 }
2104 }
2105 
2106 {
2107 // Copy longer buffer b to shorter c without targetStart
2108 b.fill(++cntr);
2109 c.fill(++cntr);
2110 const copied = b.copy(c);
2111 strictEqual(copied, c.length);
2112 for (let i = 0; i < c.length; i++) {
2113 strictEqual(c[i], b[i]);
2114 }
2115 }
2116 
2117 {
2118 // Copy starting near end of b to c
2119 b.fill(++cntr);
2120 c.fill(++cntr);
2121 const copied = b.copy(c, 0, b.length - Math.floor(c.length / 2));
2122 strictEqual(copied, Math.floor(c.length / 2));
2123 for (let i = 0; i < Math.floor(c.length / 2); i++) {
2124 strictEqual(c[i], b[b.length - Math.floor(c.length / 2) + i]);
2125 }
2126 for (let i = Math.floor(c.length / 2) + 1; i < c.length; i++) {
2127 strictEqual(c[c.length - 1], c[i]);
2128 }
2129 }
2130 
2131 {
2132 // Try to copy 513 bytes, and check we don't overrun c
2133 b.fill(++cntr);
2134 c.fill(++cntr);
2135 const copied = b.copy(c, 0, 0, 513);
2136 strictEqual(copied, c.length);
2137 for (let i = 0; i < c.length; i++) {
2138 strictEqual(c[i], b[i]);
2139 }
2140 }
2141 
2142 {
2143 // copy 768 bytes from b into b
2144 b.fill(++cntr);
2145 b.fill(++cntr, 256);
2146 const copied = b.copy(b, 0, 256, 1024);
2147 strictEqual(copied, 768);
2148 for (let i = 0; i < b.length; i++) {
2149 strictEqual(b[i], cntr);
2150 }
2151 }
2152 
2153 // Copy string longer than buffer length (failure will segfault)
2154 const bb = Buffer.allocUnsafe(10);
2155 bb.fill('hello crazy world');
2156 
2157 // Try to copy from before the beginning of b. Should not throw.
2158 b.copy(c, 0, 100, 10);
2159 
2160 // Throw with invalid source type
2161 throws(() => Buffer.prototype.copy.call(0), {
2162 code: 'ERR_INVALID_ARG_TYPE',
2163 name: 'TypeError',
2164 });
2165 
2166 // Copy throws at negative targetStart
2167 throws(() => Buffer.allocUnsafe(5).copy(Buffer.allocUnsafe(5), -1, 0), {
2168 code: 'ERR_OUT_OF_RANGE',
2169 name: 'RangeError',
2170 message:
2171 'The value of "targetStart" is out of range. ' +
2172 'It must be >= 0. Received -1',
2173 });
2174 
2175 // Copy throws at negative sourceStart
2176 throws(() => Buffer.allocUnsafe(5).copy(Buffer.allocUnsafe(5), 0, -1), {
2177 code: 'ERR_OUT_OF_RANGE',
2178 name: 'RangeError',
2179 message:
2180 'The value of "sourceStart" is out of range. ' +
2181 'It must be >= 0. Received -1',
2182 });
2183 
2184 {
2185 // Check sourceEnd resets to targetEnd if former is greater than the latter
2186 b.fill(++cntr);
2187 c.fill(++cntr);
2188 b.copy(c, 0, 0, 1025);
2189 for (let i = 0; i < c.length; i++) {
2190 strictEqual(c[i], b[i]);
2191 }
2192 }
2193 
2194 // Throw with negative sourceEnd
2195 throws(() => b.copy(c, 0, 0, -1), {
2196 code: 'ERR_OUT_OF_RANGE',
2197 name: 'RangeError',
2198 message:
2199 'The value of "sourceEnd" is out of range. ' +
2200 'It must be >= 0. Received -1',
2201 });
2202 
2203 // When sourceStart is greater than sourceEnd, zero copied
2204 strictEqual(b.copy(c, 0, 100, 10), 0);
2205 
2206 // When targetStart > targetLength, zero copied
2207 strictEqual(b.copy(c, 512, 0, 10), 0);
2208 
2209 // Test that the `target` can be a Uint8Array.
2210 {
2211 const d = new Uint8Array(c);
2212 // copy 512 bytes, from 0 to 512.
2213 b.fill(++cntr);
2214 d.fill(++cntr);
2215 const copied = b.copy(d, 0, 0, 512);
2216 strictEqual(copied, 512);
2217 for (let i = 0; i < d.length; i++) {
2218 strictEqual(d[i], b[i]);
2219 }
2220 }
2221 
2222 // Test that the source can be a Uint8Array, too.
2223 {
2224 const e = new Uint8Array(b);
2225 // copy 512 bytes, from 0 to 512.
2226 e.fill(++cntr);
2227 c.fill(++cntr);
2228 const copied = Buffer.prototype.copy.call(e, c, 0, 0, 512);
2229 strictEqual(copied, 512);
2230 for (let i = 0; i < c.length; i++) {
2231 strictEqual(c[i], e[i]);
2232 }
2233 }
2234 
2235 // https://github.com/nodejs/node/issues/23668: Do not crash for invalid input.
2236 c.fill('c');
2237 b.copy(c, 'not a valid offset');
2238 // Make sure this acted like a regular copy with `0` offset.
2239 deepStrictEqual(c, b.slice(0, c.length));
2240 
2241 {
2242 c.fill('C');
2243 throws(() => {
2244 b.copy(c, {
2245 [Symbol.toPrimitive]() {
2246 throw new Error('foo');
2247 },
2248 });
2249 }, /foo/);
2250 // No copying took place:
2251 deepStrictEqual(c.toString(), 'C'.repeat(c.length));
2252 }
2253 },
2254};
2255 
2256export const equals = {
2257 test(ctrl, env, ctx) {
2258 const b = Buffer.from('abcdf');
2259 const c = Buffer.from('abcdf');
2260 const d = Buffer.from('abcde');
2261 const e = Buffer.from('abcdef');
2262 
2263 ok(b.equals(c));
2264 ok(!c.equals(d));
2265 ok(!d.equals(e));
2266 ok(d.equals(d));
2267 ok(d.equals(new Uint8Array([0x61, 0x62, 0x63, 0x64, 0x65])));
2268 
2269 throws(() => Buffer.alloc(1).equals('abc'), {
2270 code: 'ERR_INVALID_ARG_TYPE',
2271 name: 'TypeError',
2272 });
2273 },
2274};
2275 
2276export const failedAllocTypedArrays = {
2277 test(ctrl, env, ctx) {
2278 // Test failed or zero-sized Buffer allocations not affecting typed arrays.
2279 // This test exists because of a regression that occurred. Because Buffer
2280 // instances are allocated with the same underlying allocator as TypedArrays,
2281 // but Buffer's can optional be non-zero filled, there was a regression that
2282 // occurred when a Buffer allocated failed, the internal flag specifying
2283 // whether or not to zero-fill was not being reset, causing TypedArrays to
2284 // allocate incorrectly.
2285 const zeroArray = new Uint32Array(10).fill(0);
2286 const sizes = [1e10, 0, 0.1, -1, 'a', undefined, null, NaN];
2287 const allocators = [
2288 Buffer,
2289 SlowBuffer,
2290 Buffer.alloc,
2291 Buffer.allocUnsafe,
2292 Buffer.allocUnsafeSlow,
2293 ];
2294 for (const allocator of allocators) {
2295 for (const size of sizes) {
2296 try {
2297 // Some of these allocations are known to fail. If they do,
2298 // Uint32Array should still produce a zeroed out result.
2299 allocator(size);
2300 } catch {
2301 deepStrictEqual(zeroArray, new Uint32Array(10));
2302 }
2303 }
2304 }
2305 },
2306};
2307 
2308export const fakes = {
2309 test(ctrl, env, ctx) {
2310 function FakeBuffer() {}
2311 Object.setPrototypeOf(FakeBuffer, Buffer);
2312 Object.setPrototypeOf(FakeBuffer.prototype, Buffer.prototype);
2313 
2314 const fb = new FakeBuffer();
2315 
2316 throws(function () {
2317 Buffer.from(fb);
2318 }, TypeError);
2319 
2320 throws(function () {
2321 // eslint-disable-next-line @typescript-eslint/no-unused-expressions
2322 +Buffer.prototype;
2323 }, TypeError);
2324 
2325 throws(function () {
2326 Buffer.compare(fb, Buffer.alloc(0));
2327 }, TypeError);
2328 
2329 throws(function () {
2330 fb.write('foo');
2331 }, TypeError);
2332 
2333 throws(function () {
2334 Buffer.concat([fb, fb]);
2335 }, TypeError);
2336 
2337 throws(function () {
2338 fb.toString();
2339 }, TypeError);
2340 
2341 throws(function () {
2342 fb.equals(Buffer.alloc(0));
2343 }, TypeError);
2344 
2345 throws(function () {
2346 fb.indexOf(5);
2347 }, TypeError);
2348 
2349 throws(function () {
2350 fb.readFloatLE(0);
2351 }, TypeError);
2352 
2353 throws(function () {
2354 fb.writeFloatLE(0);
2355 }, TypeError);
2356 
2357 throws(function () {
2358 fb.fill(0);
2359 }, TypeError);
2360 },
2361};
2362 
2363export const fill = {
2364 test(ctrl, env, ctx) {
2365 const SIZE = 28;
2366 const buf1 = Buffer.allocUnsafe(SIZE);
2367 const buf2 = Buffer.allocUnsafe(SIZE);
2368 
2369 // Default encoding
2370 testBufs('abc');
2371 testBufs('\u0222aa');
2372 testBufs('a\u0234b\u0235c\u0236');
2373 testBufs('abc', 4);
2374 testBufs('abc', 5);
2375 testBufs('abc', SIZE);
2376 testBufs('\u0222aa', 2);
2377 testBufs('\u0222aa', 8);
2378 testBufs('a\u0234b\u0235c\u0236', 4);
2379 testBufs('a\u0234b\u0235c\u0236', 12);
2380 testBufs('abc', 4, 1);
2381 testBufs('abc', 5, 1);
2382 testBufs('\u0222aa', 8, 1);
2383 testBufs('a\u0234b\u0235c\u0236', 4, 1);
2384 testBufs('a\u0234b\u0235c\u0236', 12, 1);
2385 
2386 // UTF8
2387 testBufs('abc', 'utf8');
2388 testBufs('\u0222aa', 'utf8');
2389 testBufs('a\u0234b\u0235c\u0236', 'utf8');
2390 testBufs('abc', 4, 'utf8');
2391 testBufs('abc', 5, 'utf8');
2392 testBufs('abc', SIZE, 'utf8');
2393 testBufs('\u0222aa', 2, 'utf8');
2394 testBufs('\u0222aa', 8, 'utf8');
2395 testBufs('a\u0234b\u0235c\u0236', 4, 'utf8');
2396 testBufs('a\u0234b\u0235c\u0236', 12, 'utf8');
2397 testBufs('abc', 4, 1, 'utf8');
2398 testBufs('abc', 5, 1, 'utf8');
2399 testBufs('\u0222aa', 8, 1, 'utf8');
2400 testBufs('a\u0234b\u0235c\u0236', 4, 1, 'utf8');
2401 testBufs('a\u0234b\u0235c\u0236', 12, 1, 'utf8');
2402 strictEqual(Buffer.allocUnsafe(1).fill(0).fill('\u0222')[0], 0xc8);
2403 
2404 // BINARY
2405 testBufs('abc', 'binary');
2406 testBufs('\u0222aa', 'binary');
2407 testBufs('a\u0234b\u0235c\u0236', 'binary');
2408 testBufs('abc', 4, 'binary');
2409 testBufs('abc', 5, 'binary');
2410 testBufs('abc', SIZE, 'binary');
2411 testBufs('\u0222aa', 2, 'binary');
2412 testBufs('\u0222aa', 8, 'binary');
2413 testBufs('a\u0234b\u0235c\u0236', 4, 'binary');
2414 testBufs('a\u0234b\u0235c\u0236', 12, 'binary');
2415 testBufs('abc', 4, 1, 'binary');
2416 testBufs('abc', 5, 1, 'binary');
2417 testBufs('\u0222aa', 8, 1, 'binary');
2418 testBufs('a\u0234b\u0235c\u0236', 4, 1, 'binary');
2419 testBufs('a\u0234b\u0235c\u0236', 12, 1, 'binary');
2420 
2421 // LATIN1
2422 testBufs('abc', 'latin1');
2423 testBufs('\u0222aa', 'latin1');
2424 testBufs('a\u0234b\u0235c\u0236', 'latin1');
2425 testBufs('abc', 4, 'latin1');
2426 testBufs('abc', 5, 'latin1');
2427 testBufs('abc', SIZE, 'latin1');
2428 testBufs('\u0222aa', 2, 'latin1');
2429 testBufs('\u0222aa', 8, 'latin1');
2430 testBufs('a\u0234b\u0235c\u0236', 4, 'latin1');
2431 testBufs('a\u0234b\u0235c\u0236', 12, 'latin1');
2432 testBufs('abc', 4, 1, 'latin1');
2433 testBufs('abc', 5, 1, 'latin1');
2434 testBufs('\u0222aa', 8, 1, 'latin1');
2435 testBufs('a\u0234b\u0235c\u0236', 4, 1, 'latin1');
2436 testBufs('a\u0234b\u0235c\u0236', 12, 1, 'latin1');
2437 
2438 // UCS2
2439 testBufs('abc', 'ucs2');
2440 testBufs('\u0222aa', 'ucs2');
2441 testBufs('a\u0234b\u0235c\u0236', 'ucs2');
2442 testBufs('abc', 4, 'ucs2');
2443 testBufs('abc', SIZE, 'ucs2');
2444 testBufs('\u0222aa', 2, 'ucs2');
2445 testBufs('\u0222aa', 8, 'ucs2');
2446 testBufs('a\u0234b\u0235c\u0236', 4, 'ucs2');
2447 testBufs('a\u0234b\u0235c\u0236', 12, 'ucs2');
2448 testBufs('abc', 4, 1, 'ucs2');
2449 testBufs('abc', 5, 1, 'ucs2');
2450 testBufs('\u0222aa', 8, 1, 'ucs2');
2451 testBufs('a\u0234b\u0235c\u0236', 4, 1, 'ucs2');
2452 testBufs('a\u0234b\u0235c\u0236', 12, 1, 'ucs2');
2453 strictEqual(Buffer.allocUnsafe(1).fill('\u0222', 'ucs2')[0], 0x22);
2454 
2455 // HEX
2456 testBufs('616263', 'hex');
2457 testBufs('c8a26161', 'hex');
2458 testBufs('61c8b462c8b563c8b6', 'hex');
2459 testBufs('616263', 4, 'hex');
2460 testBufs('616263', 5, 'hex');
2461 testBufs('616263', SIZE, 'hex');
2462 testBufs('c8a26161', 2, 'hex');
2463 testBufs('c8a26161', 8, 'hex');
2464 testBufs('61c8b462c8b563c8b6', 4, 'hex');
2465 testBufs('61c8b462c8b563c8b6', 12, 'hex');
2466 testBufs('616263', 4, 1, 'hex');
2467 testBufs('616263', 5, 1, 'hex');
2468 testBufs('c8a26161', 8, 1, 'hex');
2469 testBufs('61c8b462c8b563c8b6', 4, 1, 'hex');
2470 testBufs('61c8b462c8b563c8b6', 12, 1, 'hex');
2471 
2472 throws(
2473 () => {
2474 const buf = Buffer.allocUnsafe(SIZE);
2475 
2476 buf.fill('yKJh', 'hex');
2477 },
2478 {
2479 name: 'TypeError',
2480 }
2481 );
2482 
2483 throws(
2484 () => {
2485 const buf = Buffer.allocUnsafe(SIZE);
2486 
2487 buf.fill('\u0222', 'hex');
2488 },
2489 {
2490 name: 'TypeError',
2491 }
2492 );
2493 
2494 // BASE64
2495 testBufs('YWJj', 'base64');
2496 testBufs('yKJhYQ==', 'base64');
2497 testBufs('Yci0Ysi1Y8i2', 'base64');
2498 testBufs('YWJj', 4, 'base64');
2499 testBufs('YWJj', SIZE, 'base64');
2500 testBufs('yKJhYQ==', 2, 'base64');
2501 testBufs('yKJhYQ==', 8, 'base64');
2502 testBufs('Yci0Ysi1Y8i2', 4, 'base64');
2503 testBufs('Yci0Ysi1Y8i2', 12, 'base64');
2504 testBufs('YWJj', 4, 1, 'base64');
2505 testBufs('YWJj', 5, 1, 'base64');
2506 testBufs('yKJhYQ==', 8, 1, 'base64');
2507 testBufs('Yci0Ysi1Y8i2', 4, 1, 'base64');
2508 testBufs('Yci0Ysi1Y8i2', 12, 1, 'base64');
2509 
2510 // BASE64URL
2511 testBufs('YWJj', 'base64url');
2512 testBufs('yKJhYQ', 'base64url');
2513 testBufs('Yci0Ysi1Y8i2', 'base64url');
2514 testBufs('YWJj', 4, 'base64url');
2515 testBufs('YWJj', SIZE, 'base64url');
2516 testBufs('yKJhYQ', 2, 'base64url');
2517 testBufs('yKJhYQ', 8, 'base64url');
2518 testBufs('Yci0Ysi1Y8i2', 4, 'base64url');
2519 testBufs('Yci0Ysi1Y8i2', 12, 'base64url');
2520 testBufs('YWJj', 4, 1, 'base64url');
2521 testBufs('YWJj', 5, 1, 'base64url');
2522 testBufs('yKJhYQ', 8, 1, 'base64url');
2523 testBufs('Yci0Ysi1Y8i2', 4, 1, 'base64url');
2524 testBufs('Yci0Ysi1Y8i2', 12, 1, 'base64url');
2525 
2526 function deepStrictEqualValues(buf, arr) {
2527 for (const [index, value] of buf.entries()) {
2528 deepStrictEqual(value, arr[index]);
2529 }
2530 }
2531 
2532 const buf2Fill = Buffer.allocUnsafe(1).fill(2);
2533 deepStrictEqualValues(genBuffer(4, [buf2Fill]), [2, 2, 2, 2]);
2534 deepStrictEqualValues(genBuffer(4, [buf2Fill, 1]), [0, 2, 2, 2]);
2535 deepStrictEqualValues(genBuffer(4, [buf2Fill, 1, 3]), [0, 2, 2, 0]);
2536 deepStrictEqualValues(genBuffer(4, [buf2Fill, 1, 1]), [0, 0, 0, 0]);
2537 const hexBufFill = Buffer.allocUnsafe(2).fill(0).fill('0102', 'hex');
2538 deepStrictEqualValues(genBuffer(4, [hexBufFill]), [1, 2, 1, 2]);
2539 deepStrictEqualValues(genBuffer(4, [hexBufFill, 1]), [0, 1, 2, 1]);
2540 deepStrictEqualValues(genBuffer(4, [hexBufFill, 1, 3]), [0, 1, 2, 0]);
2541 deepStrictEqualValues(genBuffer(4, [hexBufFill, 1, 1]), [0, 0, 0, 0]);
2542 
2543 // Check exceptions
2544 [
2545 [0, -1],
2546 [0, 0, buf1.length + 1],
2547 ['', -1],
2548 ['', 0, buf1.length + 1],
2549 ['', 1, -1],
2550 ].forEach((args) => {
2551 throws(() => buf1.fill(...args), { name: 'RangeError' });
2552 });
2553 
2554 throws(() => buf1.fill('a', 0, buf1.length, 'node rocks!'), {
2555 code: 'ERR_UNKNOWN_ENCODING',
2556 name: 'TypeError',
2557 message: 'Unknown encoding: node rocks!',
2558 });
2559 
2560 [
2561 ['a', 0, 0, NaN],
2562 ['a', 0, 0, false],
2563 ].forEach((args) => {
2564 throws(() => buf1.fill(...args), {
2565 name: 'TypeError',
2566 });
2567 });
2568 
2569 throws(() => buf1.fill('a', 0, 0, 'foo'), {
2570 code: 'ERR_UNKNOWN_ENCODING',
2571 name: 'TypeError',
2572 message: 'Unknown encoding: foo',
2573 });
2574 
2575 function genBuffer(size, args) {
2576 const b = Buffer.allocUnsafe(size);
2577 return b.fill(0).fill.apply(b, args);
2578 }
2579 
2580 function bufReset() {
2581 buf1.fill(0);
2582 buf2.fill(0);
2583 }
2584 
2585 // This is mostly accurate. Except write() won't write partial bytes to the
2586 // string while fill() blindly copies bytes into memory. To account for that an
2587 // error will be thrown if not all the data can be written, and the SIZE has
2588 // been massaged to work with the input characters.
2589 function writeToFill(string, offset, end, encoding) {
2590 if (typeof offset === 'string') {
2591 encoding = offset;
2592 offset = 0;
2593 end = buf2.length;
2594 } else if (typeof end === 'string') {
2595 encoding = end;
2596 end = buf2.length;
2597 } else if (end === undefined) {
2598 end = buf2.length;
2599 }
2600 
2601 // Should never be reached.
2602 // eslint-disable-next-line no-undef
2603 if (offset < 0 || end > buf2.length) throw new ERR_OUT_OF_RANGE();
2604 
2605 if (end <= offset) return buf2;
2606 
2607 offset >>>= 0;
2608 end >>>= 0;
2609 ok(offset <= buf2.length);
2610 
2611 // Convert "end" to "length" (which write understands).
2612 const length = end - offset < 0 ? 0 : end - offset;
2613 
2614 let wasZero = false;
2615 do {
2616 const written = buf2.write(string, offset, length, encoding);
2617 offset += written;
2618 // Safety check in case write falls into infinite loop.
2619 if (written === 0) {
2620 if (wasZero) throw new Error('Could not write all data to Buffer');
2621 else wasZero = true;
2622 }
2623 } while (offset < buf2.length);
2624 
2625 return buf2;
2626 }
2627 
2628 function testBufs(string, offset, length, encoding) {
2629 bufReset();
2630 buf1.fill.apply(buf1, arguments);
2631 // Swap bytes on BE archs for ucs2 encoding.
2632 deepStrictEqual(
2633 buf1.fill.apply(buf1, arguments),
2634 writeToFill.apply(null, arguments)
2635 );
2636 }
2637 
2638 // Make sure these throw.
2639 throws(() => Buffer.allocUnsafe(8).fill('a', -1), {
2640 code: 'ERR_OUT_OF_RANGE',
2641 });
2642 throws(() => Buffer.allocUnsafe(8).fill('a', 0, 9), {
2643 code: 'ERR_OUT_OF_RANGE',
2644 });
2645 
2646 // // Make sure this doesn't hang indefinitely.
2647 Buffer.allocUnsafe(8).fill('');
2648 Buffer.alloc(8, '');
2649 
2650 {
2651 const buf = Buffer.alloc(64, 10);
2652 for (let i = 0; i < buf.length; i++) strictEqual(buf[i], 10);
2653 
2654 buf.fill(11, 0, buf.length >> 1);
2655 for (let i = 0; i < buf.length >> 1; i++) strictEqual(buf[i], 11);
2656 for (let i = (buf.length >> 1) + 1; i < buf.length; i++)
2657 strictEqual(buf[i], 10);
2658 
2659 buf.fill('h');
2660 for (let i = 0; i < buf.length; i++)
2661 strictEqual(buf[i], 'h'.charCodeAt(0));
2662 
2663 buf.fill(0);
2664 for (let i = 0; i < buf.length; i++) strictEqual(buf[i], 0);
2665 
2666 buf.fill(null);
2667 for (let i = 0; i < buf.length; i++) strictEqual(buf[i], 0);
2668 
2669 buf.fill(1, 16, 32);
2670 for (let i = 0; i < 16; i++) strictEqual(buf[i], 0);
2671 for (let i = 16; i < 32; i++) strictEqual(buf[i], 1);
2672 for (let i = 32; i < buf.length; i++) strictEqual(buf[i], 0);
2673 }
2674 
2675 {
2676 const buf = Buffer.alloc(10, 'abc');
2677 strictEqual(buf.toString(), 'abcabcabca');
2678 buf.fill('է');
2679 strictEqual(buf.toString(), 'էէէէէ');
2680 }
2681 
2682 // Make sure "end" is properly checked, even if it's magically mangled using
2683 // Symbol.toPrimitive.
2684 {
2685 throws(
2686 () => {
2687 const end = {
2688 [Symbol.toPrimitive]() {
2689 return 1;
2690 },
2691 };
2692 Buffer.alloc(1).fill(Buffer.alloc(1), 0, end);
2693 },
2694 {
2695 code: 'ERR_INVALID_ARG_TYPE',
2696 message:
2697 'The "end" argument must be of type number. Received an ' +
2698 'instance of Object',
2699 }
2700 );
2701 }
2702 
2703 // Test that bypassing 'length' won't cause an abort.
2704 // Node.js throws an error in this case because it's often the case that the
2705 // Buffer might contain uninitialized memory and we need to prevent overreads.
2706 // However, our implementation is backed entirely by ArrayBuffer/Uint8Array
2707 // and always has initialized memory, so if the user does something funky
2708 // like this, they'll get back undefineds.
2709 {
2710 const buf = Buffer.from('w00t');
2711 Object.defineProperty(buf, 'length', {
2712 value: 1337,
2713 enumerable: true,
2714 });
2715 buf.fill('');
2716 }
2717 
2718 deepStrictEqual(
2719 Buffer.allocUnsafeSlow(16).fill('ab', 'utf16le'),
2720 Buffer.from('61006200610062006100620061006200', 'hex')
2721 );
2722 
2723 deepStrictEqual(
2724 Buffer.allocUnsafeSlow(15).fill('ab', 'utf16le'),
2725 Buffer.from('610062006100620061006200610062', 'hex')
2726 );
2727 
2728 deepStrictEqual(
2729 Buffer.allocUnsafeSlow(16).fill('ab', 'utf16le'),
2730 Buffer.from('61006200610062006100620061006200', 'hex')
2731 );
2732 deepStrictEqual(
2733 Buffer.allocUnsafeSlow(16).fill('a', 'utf16le'),
2734 Buffer.from('61006100610061006100610061006100', 'hex')
2735 );
2736 
2737 strictEqual(
2738 Buffer.allocUnsafeSlow(16).fill('a', 'utf16le').toString('utf16le'),
2739 'a'.repeat(8)
2740 );
2741 strictEqual(
2742 Buffer.allocUnsafeSlow(16).fill('a', 'latin1').toString('latin1'),
2743 'a'.repeat(16)
2744 );
2745 strictEqual(
2746 Buffer.allocUnsafeSlow(16).fill('a', 'utf8').toString('utf8'),
2747 'a'.repeat(16)
2748 );
2749 
2750 strictEqual(
2751 Buffer.allocUnsafeSlow(16).fill('Љ', 'utf16le').toString('utf16le'),
2752 'Љ'.repeat(8)
2753 );
2754 strictEqual(
2755 Buffer.allocUnsafeSlow(16).fill('Љ', 'latin1').toString('latin1'),
2756 '\t'.repeat(16)
2757 );
2758 strictEqual(
2759 Buffer.allocUnsafeSlow(16).fill('Љ', 'utf8').toString('utf8'),
2760 'Љ'.repeat(8)
2761 );
2762 
2763 throws(
2764 () => {
2765 const buf = Buffer.from('a'.repeat(1000));
2766 
2767 buf.fill('This is not correctly encoded', 'hex');
2768 },
2769 {
2770 name: 'TypeError',
2771 }
2772 );
2773 
2774 {
2775 const bufEmptyString = Buffer.alloc(5, '');
2776 strictEqual(bufEmptyString.toString(), '\x00\x00\x00\x00\x00');
2777 
2778 const bufEmptyArray = Buffer.alloc(5, []);
2779 strictEqual(bufEmptyArray.toString(), '\x00\x00\x00\x00\x00');
2780 
2781 const bufEmptyBuffer = Buffer.alloc(5, Buffer.alloc(5));
2782 strictEqual(bufEmptyBuffer.toString(), '\x00\x00\x00\x00\x00');
2783 
2784 const bufZero = Buffer.alloc(5, 0);
2785 strictEqual(bufZero.toString(), '\x00\x00\x00\x00\x00');
2786 }
2787 },
2788};
2789 
2790export const includes = {
2791 test(ctrl, env, ctx) {
2792 const b = Buffer.from('abcdef');
2793 const buf_a = Buffer.from('a');
2794 const buf_bc = Buffer.from('bc');
2795 const buf_f = Buffer.from('f');
2796 const buf_z = Buffer.from('z');
2797 const buf_empty = Buffer.from('');
2798 
2799 ok(b.includes('a'));
2800 ok(!b.includes('a', 1));
2801 ok(!b.includes('a', -1));
2802 ok(!b.includes('a', -4));
2803 ok(b.includes('a', -b.length));
2804 ok(b.includes('a', NaN));
2805 ok(b.includes('a', -Infinity));
2806 ok(!b.includes('a', Infinity));
2807 ok(b.includes('bc'));
2808 ok(!b.includes('bc', 2));
2809 ok(!b.includes('bc', -1));
2810 ok(!b.includes('bc', -3));
2811 ok(b.includes('bc', -5));
2812 ok(b.includes('bc', NaN));
2813 ok(b.includes('bc', -Infinity));
2814 ok(!b.includes('bc', Infinity));
2815 ok(b.includes('f'), b.length - 1);
2816 ok(!b.includes('z'));
2817 ok(b.includes(''));
2818 ok(b.includes('', 1));
2819 ok(b.includes('', b.length + 1));
2820 ok(b.includes('', Infinity));
2821 ok(b.includes(buf_a));
2822 ok(!b.includes(buf_a, 1));
2823 ok(!b.includes(buf_a, -1));
2824 ok(!b.includes(buf_a, -4));
2825 ok(b.includes(buf_a, -b.length));
2826 ok(b.includes(buf_a, NaN));
2827 ok(b.includes(buf_a, -Infinity));
2828 ok(!b.includes(buf_a, Infinity));
2829 ok(b.includes(buf_bc));
2830 ok(!b.includes(buf_bc, 2));
2831 ok(!b.includes(buf_bc, -1));
2832 ok(!b.includes(buf_bc, -3));
2833 ok(b.includes(buf_bc, -5));
2834 ok(b.includes(buf_bc, NaN));
2835 ok(b.includes(buf_bc, -Infinity));
2836 ok(!b.includes(buf_bc, Infinity));
2837 ok(b.includes(buf_f), b.length - 1);
2838 ok(!b.includes(buf_z));
2839 ok(b.includes(buf_empty));
2840 ok(b.includes(buf_empty, 1));
2841 ok(b.includes(buf_empty, b.length + 1));
2842 ok(b.includes(buf_empty, Infinity));
2843 ok(b.includes(0x61));
2844 ok(!b.includes(0x61, 1));
2845 ok(!b.includes(0x61, -1));
2846 ok(!b.includes(0x61, -4));
2847 ok(b.includes(0x61, -b.length));
2848 ok(b.includes(0x61, NaN));
2849 ok(b.includes(0x61, -Infinity));
2850 ok(!b.includes(0x61, Infinity));
2851 ok(!b.includes(0x0));
2852 
2853 // test offsets
2854 ok(b.includes('d', 2));
2855 ok(b.includes('f', 5));
2856 ok(b.includes('f', -1));
2857 ok(!b.includes('f', 6));
2858 
2859 ok(b.includes(Buffer.from('d'), 2));
2860 ok(b.includes(Buffer.from('f'), 5));
2861 ok(b.includes(Buffer.from('f'), -1));
2862 ok(!b.includes(Buffer.from('f'), 6));
2863 
2864 ok(!Buffer.from('ff').includes(Buffer.from('f'), 1, 'ucs2'));
2865 
2866 // test hex encoding
2867 strictEqual(
2868 Buffer.from(b.toString('hex'), 'hex').includes('64', 0, 'hex'),
2869 true
2870 );
2871 strictEqual(
2872 Buffer.from(b.toString('hex'), 'hex').includes(
2873 Buffer.from('64', 'hex'),
2874 0,
2875 'hex'
2876 ),
2877 true
2878 );
2879 
2880 // Test base64 encoding
2881 strictEqual(
2882 Buffer.from(b.toString('base64'), 'base64').includes('ZA==', 0, 'base64'),
2883 true
2884 );
2885 strictEqual(
2886 Buffer.from(b.toString('base64'), 'base64').includes(
2887 Buffer.from('ZA==', 'base64'),
2888 0,
2889 'base64'
2890 ),
2891 true
2892 );
2893 
2894 // test ascii encoding
2895 strictEqual(
2896 Buffer.from(b.toString('ascii'), 'ascii').includes('d', 0, 'ascii'),
2897 true
2898 );
2899 strictEqual(
2900 Buffer.from(b.toString('ascii'), 'ascii').includes(
2901 Buffer.from('d', 'ascii'),
2902 0,
2903 'ascii'
2904 ),
2905 true
2906 );
2907 
2908 // Test latin1 encoding
2909 strictEqual(
2910 Buffer.from(b.toString('latin1'), 'latin1').includes('d', 0, 'latin1'),
2911 true
2912 );
2913 strictEqual(
2914 Buffer.from(b.toString('latin1'), 'latin1').includes(
2915 Buffer.from('d', 'latin1'),
2916 0,
2917 'latin1'
2918 ),
2919 true
2920 );
2921 
2922 // Test binary encoding
2923 strictEqual(
2924 Buffer.from(b.toString('binary'), 'binary').includes('d', 0, 'binary'),
2925 true
2926 );
2927 strictEqual(
2928 Buffer.from(b.toString('binary'), 'binary').includes(
2929 Buffer.from('d', 'binary'),
2930 0,
2931 'binary'
2932 ),
2933 true
2934 );
2935 
2936 // test ucs2 encoding
2937 let twoByteString = Buffer.from('\u039a\u0391\u03a3\u03a3\u0395', 'ucs2');
2938 
2939 ok(twoByteString.includes('\u0395', 4, 'ucs2'));
2940 ok(twoByteString.includes('\u03a3', -4, 'ucs2'));
2941 ok(twoByteString.includes('\u03a3', -6, 'ucs2'));
2942 ok(twoByteString.includes(Buffer.from('\u03a3', 'ucs2'), -6, 'ucs2'));
2943 ok(!twoByteString.includes('\u03a3', -2, 'ucs2'));
2944 
2945 const mixedByteStringUcs2 = Buffer.from(
2946 '\u039a\u0391abc\u03a3\u03a3\u0395',
2947 'ucs2'
2948 );
2949 ok(mixedByteStringUcs2.includes('bc', 0, 'ucs2'));
2950 ok(mixedByteStringUcs2.includes('\u03a3', 0, 'ucs2'));
2951 ok(!mixedByteStringUcs2.includes('\u0396', 0, 'ucs2'));
2952 
2953 ok(mixedByteStringUcs2.includes(Buffer.from('bc', 'ucs2'), 0, 'ucs2'));
2954 ok(mixedByteStringUcs2.includes(Buffer.from('\u03a3', 'ucs2'), 0, 'ucs2'));
2955 ok(!mixedByteStringUcs2.includes(Buffer.from('\u0396', 'ucs2'), 0, 'ucs2'));
2956 
2957 twoByteString = Buffer.from('\u039a\u0391\u03a3\u03a3\u0395', 'ucs2');
2958 
2959 // Test single char pattern
2960 ok(twoByteString.includes('\u039a', 0, 'ucs2'));
2961 ok(twoByteString.includes('\u0391', 0, 'ucs2'), 'Alpha');
2962 ok(twoByteString.includes('\u03a3', 0, 'ucs2'), 'First Sigma');
2963 ok(twoByteString.includes('\u03a3', 6, 'ucs2'), 'Second Sigma');
2964 ok(twoByteString.includes('\u0395', 0, 'ucs2'), 'Epsilon');
2965 ok(!twoByteString.includes('\u0392', 0, 'ucs2'), 'Not beta');
2966 
2967 // Test multi-char pattern
2968 ok(twoByteString.includes('\u039a\u0391', 0, 'ucs2'), 'Lambda Alpha');
2969 ok(twoByteString.includes('\u0391\u03a3', 0, 'ucs2'), 'Alpha Sigma');
2970 ok(twoByteString.includes('\u03a3\u03a3', 0, 'ucs2'), 'Sigma Sigma');
2971 ok(twoByteString.includes('\u03a3\u0395', 0, 'ucs2'), 'Sigma Epsilon');
2972 
2973 const mixedByteStringUtf8 = Buffer.from(
2974 '\u039a\u0391abc\u03a3\u03a3\u0395'
2975 );
2976 ok(mixedByteStringUtf8.includes('bc'));
2977 ok(mixedByteStringUtf8.includes('bc', 5));
2978 ok(mixedByteStringUtf8.includes('bc', -8));
2979 ok(mixedByteStringUtf8.includes('\u03a3'));
2980 ok(!mixedByteStringUtf8.includes('\u0396'));
2981 
2982 // Test complex string includes algorithms. Only trigger for long strings.
2983 // Long string that isn't a simple repeat of a shorter string.
2984 let longString = 'A';
2985 for (let i = 66; i < 76; i++) {
2986 // from 'B' to 'K'
2987 longString = longString + String.fromCharCode(i) + longString;
2988 }
2989 
2990 const longBufferString = Buffer.from(longString);
2991 
2992 // Pattern of 15 chars, repeated every 16 chars in long
2993 let pattern = 'ABACABADABACABA';
2994 for (let i = 0; i < longBufferString.length - pattern.length; i += 7) {
2995 const includes = longBufferString.includes(pattern, i);
2996 ok(includes, `Long ABACABA...-string at index ${i}`);
2997 }
2998 ok(longBufferString.includes('AJABACA'), 'Long AJABACA, First J');
2999 ok(longBufferString.includes('AJABACA', 511), 'Long AJABACA, Second J');
3000 
3001 pattern = 'JABACABADABACABA';
3002 ok(longBufferString.includes(pattern), 'Long JABACABA..., First J');
3003 ok(longBufferString.includes(pattern, 512), 'Long JABACABA..., Second J');
3004 
3005 // Search for a non-ASCII string in a pure ASCII string.
3006 const asciiString = Buffer.from(
3007 'arglebargleglopglyfarglebargleglopglyfarglebargleglopglyf'
3008 );
3009 ok(!asciiString.includes('\x2061'));
3010 ok(asciiString.includes('leb', 0));
3011 
3012 // Search in string containing many non-ASCII chars.
3013 const allCodePoints = [];
3014 for (let i = 0; i < 65534; i++) allCodePoints[i] = i;
3015 const allCharsString =
3016 String.fromCharCode.apply(String, allCodePoints) +
3017 String.fromCharCode(65534, 65535);
3018 const allCharsBufferUtf8 = Buffer.from(allCharsString);
3019 const allCharsBufferUcs2 = Buffer.from(allCharsString, 'ucs2');
3020 
3021 // Search for string long enough to trigger complex search with ASCII pattern
3022 // and UC16 subject.
3023 ok(!allCharsBufferUtf8.includes('notfound'));
3024 ok(!allCharsBufferUcs2.includes('notfound'));
3025 
3026 // Find substrings in Utf8.
3027 let lengths = [1, 3, 15]; // Single char, simple and complex.
3028 let indices = [0x5, 0x60, 0x400, 0x680, 0x7ee, 0xff02, 0x16610, 0x2f77b];
3029 for (let lengthIndex = 0; lengthIndex < lengths.length; lengthIndex++) {
3030 for (let i = 0; i < indices.length; i++) {
3031 const index = indices[i];
3032 let length = lengths[lengthIndex];
3033 
3034 if (index + length > 0x7f) {
3035 length = 2 * length;
3036 }
3037 
3038 if (index + length > 0x7ff) {
3039 length = 3 * length;
3040 }
3041 
3042 if (index + length > 0xffff) {
3043 length = 4 * length;
3044 }
3045 
3046 const patternBufferUtf8 = allCharsBufferUtf8.slice(
3047 index,
3048 index + length
3049 );
3050 ok(index, allCharsBufferUtf8.includes(patternBufferUtf8));
3051 
3052 const patternStringUtf8 = patternBufferUtf8.toString();
3053 ok(index, allCharsBufferUtf8.includes(patternStringUtf8));
3054 }
3055 }
3056 
3057 // Find substrings in Usc2.
3058 lengths = [2, 4, 16]; // Single char, simple and complex.
3059 indices = [0x5, 0x65, 0x105, 0x205, 0x285, 0x2005, 0x2085, 0xfff0];
3060 for (let lengthIndex = 0; lengthIndex < lengths.length; lengthIndex++) {
3061 for (let i = 0; i < indices.length; i++) {
3062 const index = indices[i] * 2;
3063 const length = lengths[lengthIndex];
3064 
3065 const patternBufferUcs2 = allCharsBufferUcs2.slice(
3066 index,
3067 index + length
3068 );
3069 ok(allCharsBufferUcs2.includes(patternBufferUcs2, 0, 'ucs2'));
3070 
3071 const patternStringUcs2 = patternBufferUcs2.toString('ucs2');
3072 ok(allCharsBufferUcs2.includes(patternStringUcs2, 0, 'ucs2'));
3073 }
3074 }
3075 
3076 [() => {}, {}, []].forEach((val) => {
3077 throws(() => b.includes(val), {
3078 name: 'TypeError',
3079 });
3080 });
3081 
3082 // Test truncation of Number arguments to uint8
3083 {
3084 const buf = Buffer.from('this is a test');
3085 ok(buf.includes(0x6973));
3086 ok(buf.includes(0x697320));
3087 ok(buf.includes(0x69732069));
3088 ok(buf.includes(0x697374657374));
3089 ok(buf.includes(0x69737374));
3090 ok(buf.includes(0x69737465));
3091 ok(buf.includes(0x69737465));
3092 ok(buf.includes(-140));
3093 ok(buf.includes(-152));
3094 ok(!buf.includes(0xff));
3095 ok(!buf.includes(0xffff));
3096 }
3097 },
3098};
3099 
3100export const indexof = {
3101 test(ctrl, env, ctx) {
3102 const b = Buffer.from('abcdef');
3103 const buf_a = Buffer.from('a');
3104 const buf_bc = Buffer.from('bc');
3105 const buf_f = Buffer.from('f');
3106 const buf_z = Buffer.from('z');
3107 const buf_empty = Buffer.from('');
3108 
3109 const s = 'abcdef';
3110 
3111 strictEqual(b.indexOf('a'), 0);
3112 strictEqual(b.indexOf('a', 1), -1);
3113 strictEqual(b.indexOf('a', -1), -1);
3114 strictEqual(b.indexOf('a', -4), -1);
3115 strictEqual(b.indexOf('a', -b.length), 0);
3116 strictEqual(b.indexOf('a', NaN), 0);
3117 strictEqual(b.indexOf('a', -Infinity), 0);
3118 strictEqual(b.indexOf('a', Infinity), -1);
3119 strictEqual(b.indexOf('bc'), 1);
3120 strictEqual(b.indexOf('bc', 2), -1);
3121 strictEqual(b.indexOf('bc', -1), -1);
3122 strictEqual(b.indexOf('bc', -3), -1);
3123 strictEqual(b.indexOf('bc', -5), 1);
3124 strictEqual(b.indexOf('bc', NaN), 1);
3125 strictEqual(b.indexOf('bc', -Infinity), 1);
3126 strictEqual(b.indexOf('bc', Infinity), -1);
3127 strictEqual(b.indexOf('f'), b.length - 1);
3128 strictEqual(b.indexOf('z'), -1);
3129 strictEqual(b.indexOf(''), 0);
3130 strictEqual(b.indexOf('', 1), 1);
3131 strictEqual(b.indexOf('', b.length + 1), b.length);
3132 strictEqual(b.indexOf('', Infinity), b.length);
3133 strictEqual(b.indexOf(buf_a), 0);
3134 strictEqual(b.indexOf(buf_a, 1), -1);
3135 strictEqual(b.indexOf(buf_a, -1), -1);
3136 strictEqual(b.indexOf(buf_a, -4), -1);
3137 strictEqual(b.indexOf(buf_a, -b.length), 0);
3138 strictEqual(b.indexOf(buf_a, NaN), 0);
3139 strictEqual(b.indexOf(buf_a, -Infinity), 0);
3140 strictEqual(b.indexOf(buf_a, Infinity), -1);
3141 strictEqual(b.indexOf(buf_bc), 1);
3142 strictEqual(b.indexOf(buf_bc, 2), -1);
3143 strictEqual(b.indexOf(buf_bc, -1), -1);
3144 strictEqual(b.indexOf(buf_bc, -3), -1);
3145 strictEqual(b.indexOf(buf_bc, -5), 1);
3146 strictEqual(b.indexOf(buf_bc, NaN), 1);
3147 strictEqual(b.indexOf(buf_bc, -Infinity), 1);
3148 strictEqual(b.indexOf(buf_bc, Infinity), -1);
3149 strictEqual(b.indexOf(buf_f), b.length - 1);
3150 strictEqual(b.indexOf(buf_z), -1);
3151 strictEqual(b.indexOf(buf_empty), 0);
3152 strictEqual(b.indexOf(buf_empty, 1), 1);
3153 strictEqual(b.indexOf(buf_empty, b.length + 1), b.length);
3154 strictEqual(b.indexOf(buf_empty, Infinity), b.length);
3155 strictEqual(b.indexOf(0x61), 0);
3156 strictEqual(b.indexOf(0x61, 1), -1);
3157 strictEqual(b.indexOf(0x61, -1), -1);
3158 strictEqual(b.indexOf(0x61, -4), -1);
3159 strictEqual(b.indexOf(0x61, -b.length), 0);
3160 strictEqual(b.indexOf(0x61, NaN), 0);
3161 strictEqual(b.indexOf(0x61, -Infinity), 0);
3162 strictEqual(b.indexOf(0x61, Infinity), -1);
3163 strictEqual(b.indexOf(0x0), -1);
3164 
3165 // test offsets
3166 strictEqual(b.indexOf('d', 2), 3);
3167 strictEqual(b.indexOf('f', 5), 5);
3168 strictEqual(b.indexOf('f', -1), 5);
3169 strictEqual(b.indexOf('f', 6), -1);
3170 
3171 strictEqual(b.indexOf(Buffer.from('d'), 2), 3);
3172 strictEqual(b.indexOf(Buffer.from('f'), 5), 5);
3173 strictEqual(b.indexOf(Buffer.from('f'), -1), 5);
3174 strictEqual(b.indexOf(Buffer.from('f'), 6), -1);
3175 
3176 strictEqual(Buffer.from('ff').indexOf(Buffer.from('f'), 1, 'ucs2'), -1);
3177 
3178 // Test invalid and uppercase encoding
3179 strictEqual(b.indexOf('b', 'utf8'), 1);
3180 strictEqual(b.indexOf('b', 'UTF8'), 1);
3181 strictEqual(b.indexOf('62', 'HEX'), 1);
3182 
3183 throws(() => b.indexOf('bad', 'enc'), /Unknown encoding: enc/);
3184 
3185 // test hex encoding
3186 strictEqual(
3187 Buffer.from(b.toString('hex'), 'hex').indexOf('64', 0, 'hex'),
3188 3
3189 );
3190 strictEqual(
3191 Buffer.from(b.toString('hex'), 'hex').indexOf(
3192 Buffer.from('64', 'hex'),
3193 0,
3194 'hex'
3195 ),
3196 3
3197 );
3198 
3199 // Test base64 encoding
3200 strictEqual(
3201 Buffer.from(b.toString('base64'), 'base64').indexOf('ZA==', 0, 'base64'),
3202 3
3203 );
3204 strictEqual(
3205 Buffer.from(b.toString('base64'), 'base64').indexOf(
3206 Buffer.from('ZA==', 'base64'),
3207 0,
3208 'base64'
3209 ),
3210 3
3211 );
3212 
3213 // Test base64url encoding
3214 strictEqual(
3215 Buffer.from(b.toString('base64url'), 'base64url').indexOf(
3216 'ZA==',
3217 0,
3218 'base64url'
3219 ),
3220 3
3221 );
3222 
3223 // test ascii encoding
3224 strictEqual(
3225 Buffer.from(b.toString('ascii'), 'ascii').indexOf('d', 0, 'ascii'),
3226 3
3227 );
3228 strictEqual(
3229 Buffer.from(b.toString('ascii'), 'ascii').indexOf(
3230 Buffer.from('d', 'ascii'),
3231 0,
3232 'ascii'
3233 ),
3234 3
3235 );
3236 
3237 // Test latin1 encoding
3238 strictEqual(
3239 Buffer.from(b.toString('latin1'), 'latin1').indexOf('d', 0, 'latin1'),
3240 3
3241 );
3242 strictEqual(
3243 Buffer.from(b.toString('latin1'), 'latin1').indexOf(
3244 Buffer.from('d', 'latin1'),
3245 0,
3246 'latin1'
3247 ),
3248 3
3249 );
3250 strictEqual(
3251 Buffer.from('aa\u00e8aa', 'latin1').indexOf('\u00e8', 'latin1'),
3252 2
3253 );
3254 strictEqual(Buffer.from('\u00e8', 'latin1').indexOf('\u00e8', 'latin1'), 0);
3255 strictEqual(
3256 Buffer.from('\u00e8', 'latin1').indexOf(
3257 Buffer.from('\u00e8', 'latin1'),
3258 'latin1'
3259 ),
3260 0
3261 );
3262 
3263 // Test binary encoding
3264 strictEqual(
3265 Buffer.from(b.toString('binary'), 'binary').indexOf('d', 0, 'binary'),
3266 3
3267 );
3268 strictEqual(
3269 Buffer.from(b.toString('binary'), 'binary').indexOf(
3270 Buffer.from('d', 'binary'),
3271 0,
3272 'binary'
3273 ),
3274 3
3275 );
3276 strictEqual(
3277 Buffer.from('aa\u00e8aa', 'binary').indexOf('\u00e8', 'binary'),
3278 2
3279 );
3280 strictEqual(Buffer.from('\u00e8', 'binary').indexOf('\u00e8', 'binary'), 0);
3281 strictEqual(
3282 Buffer.from('\u00e8', 'binary').indexOf(
3283 Buffer.from('\u00e8', 'binary'),
3284 'binary'
3285 ),
3286 0
3287 );
3288 
3289 // Test optional offset with passed encoding
3290 strictEqual(Buffer.from('aaaa0').indexOf('30', 'hex'), 4);
3291 strictEqual(Buffer.from('aaaa00a').indexOf('3030', 'hex'), 4);
3292 
3293 {
3294 // Test usc2 and utf16le encoding
3295 ['ucs2', 'utf16le'].forEach((encoding) => {
3296 const twoByteString = Buffer.from(
3297 '\u039a\u0391\u03a3\u03a3\u0395',
3298 encoding
3299 );
3300 
3301 strictEqual(twoByteString.indexOf('\u0395', 4, encoding), 8);
3302 strictEqual(twoByteString.indexOf('\u03a3', -4, encoding), 6);
3303 strictEqual(twoByteString.indexOf('\u03a3', -6, encoding), 4);
3304 strictEqual(
3305 twoByteString.indexOf(Buffer.from('\u03a3', encoding), -6, encoding),
3306 4
3307 );
3308 strictEqual(-1, twoByteString.indexOf('\u03a3', -2, encoding));
3309 });
3310 }
3311 
3312 const mixedByteStringUcs2 = Buffer.from(
3313 '\u039a\u0391abc\u03a3\u03a3\u0395',
3314 'ucs2'
3315 );
3316 strictEqual(mixedByteStringUcs2.indexOf('bc', 0, 'ucs2'), 6);
3317 strictEqual(mixedByteStringUcs2.indexOf('\u03a3', 0, 'ucs2'), 10);
3318 strictEqual(-1, mixedByteStringUcs2.indexOf('\u0396', 0, 'ucs2'));
3319 
3320 strictEqual(
3321 mixedByteStringUcs2.indexOf(Buffer.from('bc', 'ucs2'), 0, 'ucs2'),
3322 6
3323 );
3324 strictEqual(
3325 mixedByteStringUcs2.indexOf(Buffer.from('\u03a3', 'ucs2'), 0, 'ucs2'),
3326 10
3327 );
3328 strictEqual(
3329 -1,
3330 mixedByteStringUcs2.indexOf(Buffer.from('\u0396', 'ucs2'), 0, 'ucs2')
3331 );
3332 
3333 {
3334 const twoByteString = Buffer.from(
3335 '\u039a\u0391\u03a3\u03a3\u0395',
3336 'ucs2'
3337 );
3338 
3339 // Test single char pattern
3340 strictEqual(twoByteString.indexOf('\u039a', 0, 'ucs2'), 0);
3341 let index = twoByteString.indexOf('\u0391', 0, 'ucs2');
3342 strictEqual(index, 2, `Alpha - at index ${index}`);
3343 index = twoByteString.indexOf('\u03a3', 0, 'ucs2');
3344 strictEqual(index, 4, `First Sigma - at index ${index}`);
3345 index = twoByteString.indexOf('\u03a3', 6, 'ucs2');
3346 strictEqual(index, 6, `Second Sigma - at index ${index}`);
3347 index = twoByteString.indexOf('\u0395', 0, 'ucs2');
3348 strictEqual(index, 8, `Epsilon - at index ${index}`);
3349 index = twoByteString.indexOf('\u0392', 0, 'ucs2');
3350 strictEqual(-1, index, `Not beta - at index ${index}`);
3351 
3352 // Test multi-char pattern
3353 index = twoByteString.indexOf('\u039a\u0391', 0, 'ucs2');
3354 strictEqual(index, 0, `Lambda Alpha - at index ${index}`);
3355 index = twoByteString.indexOf('\u0391\u03a3', 0, 'ucs2');
3356 strictEqual(index, 2, `Alpha Sigma - at index ${index}`);
3357 index = twoByteString.indexOf('\u03a3\u03a3', 0, 'ucs2');
3358 strictEqual(index, 4, `Sigma Sigma - at index ${index}`);
3359 index = twoByteString.indexOf('\u03a3\u0395', 0, 'ucs2');
3360 strictEqual(index, 6, `Sigma Epsilon - at index ${index}`);
3361 }
3362 
3363 const mixedByteStringUtf8 = Buffer.from(
3364 '\u039a\u0391abc\u03a3\u03a3\u0395'
3365 );
3366 strictEqual(mixedByteStringUtf8.indexOf('bc'), 5);
3367 strictEqual(mixedByteStringUtf8.indexOf('bc', 5), 5);
3368 strictEqual(mixedByteStringUtf8.indexOf('bc', -8), 5);
3369 strictEqual(mixedByteStringUtf8.indexOf('\u03a3'), 7);
3370 strictEqual(mixedByteStringUtf8.indexOf('\u0396'), -1);
3371 
3372 // Test complex string indexOf algorithms. Only trigger for long strings.
3373 // Long string that isn't a simple repeat of a shorter string.
3374 let longString = 'A';
3375 for (let i = 66; i < 76; i++) {
3376 // from 'B' to 'K'
3377 longString = longString + String.fromCharCode(i) + longString;
3378 }
3379 
3380 const longBufferString = Buffer.from(longString);
3381 
3382 // Pattern of 15 chars, repeated every 16 chars in long
3383 let pattern = 'ABACABADABACABA';
3384 for (let i = 0; i < longBufferString.length - pattern.length; i += 7) {
3385 const index = longBufferString.indexOf(pattern, i);
3386 strictEqual(
3387 (i + 15) & ~0xf,
3388 index,
3389 `Long ABACABA...-string at index ${i}`
3390 );
3391 }
3392 
3393 let index = longBufferString.indexOf('AJABACA');
3394 strictEqual(index, 510, `Long AJABACA, First J - at index ${index}`);
3395 index = longBufferString.indexOf('AJABACA', 511);
3396 strictEqual(index, 1534, `Long AJABACA, Second J - at index ${index}`);
3397 
3398 pattern = 'JABACABADABACABA';
3399 index = longBufferString.indexOf(pattern);
3400 strictEqual(index, 511, `Long JABACABA..., First J - at index ${index}`);
3401 index = longBufferString.indexOf(pattern, 512);
3402 strictEqual(index, 1535, `Long JABACABA..., Second J - at index ${index}`);
3403 
3404 // Search for a non-ASCII string in a pure ASCII string.
3405 const asciiString = Buffer.from(
3406 'arglebargleglopglyfarglebargleglopglyfarglebargleglopglyf'
3407 );
3408 strictEqual(-1, asciiString.indexOf('\x2061'));
3409 strictEqual(asciiString.indexOf('leb', 0), 3);
3410 
3411 // Search in string containing many non-ASCII chars.
3412 const allCodePoints = [];
3413 for (let i = 0; i < 65534; i++) allCodePoints[i] = i;
3414 const allCharsString =
3415 String.fromCharCode.apply(String, allCodePoints) +
3416 String.fromCharCode(65534, 65535);
3417 const allCharsBufferUtf8 = Buffer.from(allCharsString);
3418 const allCharsBufferUcs2 = Buffer.from(allCharsString, 'ucs2');
3419 
3420 // Search for string long enough to trigger complex search with ASCII pattern
3421 // and UC16 subject.
3422 strictEqual(-1, allCharsBufferUtf8.indexOf('notfound'));
3423 strictEqual(-1, allCharsBufferUcs2.indexOf('notfound'));
3424 
3425 // Needle is longer than haystack, but only because it's encoded as UTF-16
3426 strictEqual(Buffer.from('aaaa').indexOf('a'.repeat(4), 'ucs2'), -1);
3427 
3428 strictEqual(Buffer.from('aaaa').indexOf('a'.repeat(4), 'utf8'), 0);
3429 strictEqual(Buffer.from('aaaa').indexOf('你好', 'ucs2'), -1);
3430 
3431 // Haystack has odd length, but the needle is UCS2.
3432 strictEqual(Buffer.from('aaaaa').indexOf('b', 'ucs2'), -1);
3433 
3434 {
3435 // Find substrings in Utf8.
3436 const lengths = [1, 3, 15]; // Single char, simple and complex.
3437 const indices = [
3438 0x5, 0x60, 0x400, 0x680, 0x7ee, 0xff02, 0x16610, 0x2f77b,
3439 ];
3440 for (let lengthIndex = 0; lengthIndex < lengths.length; lengthIndex++) {
3441 for (let i = 0; i < indices.length; i++) {
3442 const index = indices[i];
3443 let length = lengths[lengthIndex];
3444 
3445 if (index + length > 0x7f) {
3446 length = 2 * length;
3447 }
3448 
3449 if (index + length > 0x7ff) {
3450 length = 3 * length;
3451 }
3452 
3453 if (index + length > 0xffff) {
3454 length = 4 * length;
3455 }
3456 
3457 const patternBufferUtf8 = allCharsBufferUtf8.slice(
3458 index,
3459 index + length
3460 );
3461 strictEqual(index, allCharsBufferUtf8.indexOf(patternBufferUtf8));
3462 
3463 const patternStringUtf8 = patternBufferUtf8.toString();
3464 strictEqual(index, allCharsBufferUtf8.indexOf(patternStringUtf8));
3465 }
3466 }
3467 }
3468 
3469 {
3470 // Find substrings in Usc2.
3471 const lengths = [2, 4, 16]; // Single char, simple and complex.
3472 const indices = [0x5, 0x65, 0x105, 0x205, 0x285, 0x2005, 0x2085, 0xfff0];
3473 for (let lengthIndex = 0; lengthIndex < lengths.length; lengthIndex++) {
3474 for (let i = 0; i < indices.length; i++) {
3475 const index = indices[i] * 2;
3476 const length = lengths[lengthIndex];
3477 
3478 const patternBufferUcs2 = allCharsBufferUcs2.slice(
3479 index,
3480 index + length
3481 );
3482 strictEqual(
3483 index,
3484 allCharsBufferUcs2.indexOf(patternBufferUcs2, 0, 'ucs2')
3485 );
3486 
3487 const patternStringUcs2 = patternBufferUcs2.toString('ucs2');
3488 strictEqual(
3489 index,
3490 allCharsBufferUcs2.indexOf(patternStringUcs2, 0, 'ucs2')
3491 );
3492 }
3493 }
3494 }
3495 
3496 [() => {}, {}, []].forEach((val) => {
3497 throws(() => b.indexOf(val), {
3498 name: 'TypeError',
3499 });
3500 });
3501 
3502 // Test weird offset arguments.
3503 // The following offsets coerce to NaN or 0, searching the whole Buffer
3504 strictEqual(b.indexOf('b', undefined), 1);
3505 strictEqual(b.indexOf('b', {}), 1);
3506 strictEqual(b.indexOf('b', 0), 1);
3507 strictEqual(b.indexOf('b', null), 1);
3508 strictEqual(b.indexOf('b', []), 1);
3509 
3510 // The following offset coerces to 2, in other words +[2] === 2
3511 strictEqual(b.indexOf('b', [2]), -1);
3512 
3513 // Behavior should match String.indexOf()
3514 strictEqual(b.indexOf('b', undefined), s.indexOf('b', undefined));
3515 strictEqual(b.indexOf('b', {}), s.indexOf('b', {}));
3516 strictEqual(b.indexOf('b', 0), s.indexOf('b', 0));
3517 strictEqual(b.indexOf('b', null), s.indexOf('b', null));
3518 strictEqual(b.indexOf('b', []), s.indexOf('b', []));
3519 strictEqual(b.indexOf('b', [2]), s.indexOf('b', [2]));
3520 
3521 // All code for handling encodings is shared between Buffer.indexOf and
3522 // Buffer.lastIndexOf, so only testing the separate lastIndexOf semantics.
3523 
3524 // Test lastIndexOf basic functionality; Buffer b contains 'abcdef'.
3525 // lastIndexOf string:
3526 strictEqual(b.lastIndexOf('a'), 0);
3527 strictEqual(b.lastIndexOf('a', 1), 0);
3528 strictEqual(b.lastIndexOf('b', 1), 1);
3529 strictEqual(b.lastIndexOf('c', 1), -1);
3530 strictEqual(b.lastIndexOf('a', -1), 0);
3531 strictEqual(b.lastIndexOf('a', -4), 0);
3532 strictEqual(b.lastIndexOf('a', -b.length), 0);
3533 strictEqual(b.lastIndexOf('a', -b.length - 1), -1);
3534 strictEqual(b.lastIndexOf('a', NaN), 0);
3535 strictEqual(b.lastIndexOf('a', -Infinity), -1);
3536 strictEqual(b.lastIndexOf('a', Infinity), 0);
3537 // lastIndexOf Buffer:
3538 strictEqual(b.lastIndexOf(buf_a), 0);
3539 strictEqual(b.lastIndexOf(buf_a, 1), 0);
3540 strictEqual(b.lastIndexOf(buf_a, -1), 0);
3541 strictEqual(b.lastIndexOf(buf_a, -4), 0);
3542 strictEqual(b.lastIndexOf(buf_a, -b.length), 0);
3543 strictEqual(b.lastIndexOf(buf_a, -b.length - 1), -1);
3544 strictEqual(b.lastIndexOf(buf_a, NaN), 0);
3545 strictEqual(b.lastIndexOf(buf_a, -Infinity), -1);
3546 strictEqual(b.lastIndexOf(buf_a, Infinity), 0);
3547 strictEqual(b.lastIndexOf(buf_bc), 1);
3548 strictEqual(b.lastIndexOf(buf_bc, 2), 1);
3549 strictEqual(b.lastIndexOf(buf_bc, -1), 1);
3550 strictEqual(b.lastIndexOf(buf_bc, -3), 1);
3551 strictEqual(b.lastIndexOf(buf_bc, -5), 1);
3552 strictEqual(b.lastIndexOf(buf_bc, -6), -1);
3553 strictEqual(b.lastIndexOf(buf_bc, NaN), 1);
3554 strictEqual(b.lastIndexOf(buf_bc, -Infinity), -1);
3555 strictEqual(b.lastIndexOf(buf_bc, Infinity), 1);
3556 strictEqual(b.lastIndexOf(buf_f), b.length - 1);
3557 strictEqual(b.lastIndexOf(buf_z), -1);
3558 strictEqual(b.lastIndexOf(buf_empty), b.length);
3559 strictEqual(b.lastIndexOf(buf_empty, 1), 1);
3560 strictEqual(b.lastIndexOf(buf_empty, b.length + 1), b.length);
3561 strictEqual(b.lastIndexOf(buf_empty, Infinity), b.length);
3562 // lastIndexOf number:
3563 strictEqual(b.lastIndexOf(0x61), 0);
3564 strictEqual(b.lastIndexOf(0x61, 1), 0);
3565 strictEqual(b.lastIndexOf(0x61, -1), 0);
3566 strictEqual(b.lastIndexOf(0x61, -4), 0);
3567 strictEqual(b.lastIndexOf(0x61, -b.length), 0);
3568 strictEqual(b.lastIndexOf(0x61, -b.length - 1), -1);
3569 strictEqual(b.lastIndexOf(0x61, NaN), 0);
3570 strictEqual(b.lastIndexOf(0x61, -Infinity), -1);
3571 strictEqual(b.lastIndexOf(0x61, Infinity), 0);
3572 strictEqual(b.lastIndexOf(0x0), -1);
3573 
3574 // Test weird offset arguments.
3575 // The following offsets coerce to NaN, searching the whole Buffer
3576 strictEqual(b.lastIndexOf('b', undefined), 1);
3577 strictEqual(b.lastIndexOf('b', {}), 1);
3578 
3579 // The following offsets coerce to 0
3580 strictEqual(b.lastIndexOf('b', 0), -1);
3581 strictEqual(b.lastIndexOf('b', null), -1);
3582 strictEqual(b.lastIndexOf('b', []), -1);
3583 
3584 // The following offset coerces to 2, in other words +[2] === 2
3585 strictEqual(b.lastIndexOf('b', [2]), 1);
3586 
3587 // Behavior should match String.lastIndexOf()
3588 strictEqual(b.lastIndexOf('b', undefined), s.lastIndexOf('b', undefined));
3589 strictEqual(b.lastIndexOf('b', {}), s.lastIndexOf('b', {}));
3590 strictEqual(b.lastIndexOf('b', 0), s.lastIndexOf('b', 0));
3591 strictEqual(b.lastIndexOf('b', null), s.lastIndexOf('b', null));
3592 strictEqual(b.lastIndexOf('b', []), s.lastIndexOf('b', []));
3593 strictEqual(b.lastIndexOf('b', [2]), s.lastIndexOf('b', [2]));
3594 
3595 // Test needles longer than the haystack.
3596 strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa', 'ucs2'), -1);
3597 strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa', 'utf8'), -1);
3598 strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa', 'latin1'), -1);
3599 strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa', 'binary'), -1);
3600 strictEqual(b.lastIndexOf(Buffer.from('aaaaaaaaaaaaaaa')), -1);
3601 strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa', 2, 'ucs2'), -1);
3602 strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa', 3, 'utf8'), -1);
3603 strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa', 5, 'latin1'), -1);
3604 strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa', 5, 'binary'), -1);
3605 strictEqual(b.lastIndexOf(Buffer.from('aaaaaaaaaaaaaaa'), 7), -1);
3606 
3607 // 你好 expands to a total of 6 bytes using UTF-8 and 4 bytes using UTF-16
3608 strictEqual(buf_bc.lastIndexOf('你好', 'ucs2'), -1);
3609 strictEqual(buf_bc.lastIndexOf('你好', 'utf8'), -1);
3610 strictEqual(buf_bc.lastIndexOf('你好', 'latin1'), -1);
3611 strictEqual(buf_bc.lastIndexOf('你好', 'binary'), -1);
3612 strictEqual(buf_bc.lastIndexOf(Buffer.from('你好')), -1);
3613 strictEqual(buf_bc.lastIndexOf('你好', 2, 'ucs2'), -1);
3614 strictEqual(buf_bc.lastIndexOf('你好', 3, 'utf8'), -1);
3615 strictEqual(buf_bc.lastIndexOf('你好', 5, 'latin1'), -1);
3616 strictEqual(buf_bc.lastIndexOf('你好', 5, 'binary'), -1);
3617 strictEqual(buf_bc.lastIndexOf(Buffer.from('你好'), 7), -1);
3618 
3619 // Test lastIndexOf on a longer buffer:
3620 const bufferString = Buffer.from('a man a plan a canal panama');
3621 strictEqual(bufferString.lastIndexOf('canal'), 15);
3622 strictEqual(bufferString.lastIndexOf('panama'), 21);
3623 strictEqual(bufferString.lastIndexOf('a man a plan a canal panama'), 0);
3624 strictEqual(-1, bufferString.lastIndexOf('a man a plan a canal mexico'));
3625 strictEqual(
3626 -1,
3627 bufferString.lastIndexOf('a man a plan a canal mexico city')
3628 );
3629 strictEqual(-1, bufferString.lastIndexOf(Buffer.from('a'.repeat(1000))));
3630 strictEqual(bufferString.lastIndexOf('a man a plan', 4), 0);
3631 strictEqual(bufferString.lastIndexOf('a '), 13);
3632 strictEqual(bufferString.lastIndexOf('a ', 13), 13);
3633 strictEqual(bufferString.lastIndexOf('a ', 12), 6);
3634 strictEqual(bufferString.lastIndexOf('a ', 5), 0);
3635 strictEqual(bufferString.lastIndexOf('a ', -1), 13);
3636 strictEqual(bufferString.lastIndexOf('a ', -27), 0);
3637 strictEqual(-1, bufferString.lastIndexOf('a ', -28));
3638 
3639 // Test lastIndexOf for the case that the first character can be found,
3640 // but in a part of the buffer that does not make search to search
3641 // due do length constraints.
3642 const abInUCS2 = Buffer.from('ab', 'ucs2');
3643 strictEqual(-1, Buffer.from('µaaaa¶bbbb', 'latin1').lastIndexOf('µ'));
3644 strictEqual(-1, Buffer.from('µaaaa¶bbbb', 'binary').lastIndexOf('µ'));
3645 strictEqual(-1, Buffer.from('bc').lastIndexOf('ab'));
3646 strictEqual(-1, Buffer.from('abc').lastIndexOf('qa'));
3647 strictEqual(-1, Buffer.from('abcdef').lastIndexOf('qabc'));
3648 strictEqual(-1, Buffer.from('bc').lastIndexOf(Buffer.from('ab')));
3649 strictEqual(-1, Buffer.from('bc', 'ucs2').lastIndexOf('ab', 'ucs2'));
3650 strictEqual(-1, Buffer.from('bc', 'ucs2').lastIndexOf(abInUCS2));
3651 
3652 strictEqual(Buffer.from('abc').lastIndexOf('ab'), 0);
3653 strictEqual(Buffer.from('abc').lastIndexOf('ab', 1), 0);
3654 strictEqual(Buffer.from('abc').lastIndexOf('ab', 2), 0);
3655 strictEqual(Buffer.from('abc').lastIndexOf('ab', 3), 0);
3656 
3657 // The above tests test the LINEAR and SINGLE-CHAR strategies.
3658 // Now, we test the BOYER-MOORE-HORSPOOL strategy.
3659 // Test lastIndexOf on a long buffer w multiple matches:
3660 // pattern = 'JABACABADABACABA';
3661 strictEqual(longBufferString.lastIndexOf(pattern), 1535);
3662 strictEqual(longBufferString.lastIndexOf(pattern, 1535), 1535);
3663 strictEqual(longBufferString.lastIndexOf(pattern, 1534), 511);
3664 
3665 // Generate a really long Thue-Morse sequence of 'yolo' and 'swag',
3666 // "yolo swag swag yolo swag yolo yolo swag" ..., goes on for about 5MB.
3667 // This is hard to search because it all looks similar, but never repeats.
3668 
3669 // countBits returns the number of bits in the binary representation of n.
3670 function countBits(n) {
3671 let count;
3672 for (count = 0; n > 0; count++) {
3673 n = n & (n - 1); // remove top bit
3674 }
3675 return count;
3676 }
3677 const parts = [];
3678 for (let i = 0; i < 1000000; i++) {
3679 parts.push(countBits(i) % 2 === 0 ? 'yolo' : 'swag');
3680 }
3681 const reallyLong = Buffer.from(parts.join(' '));
3682 strictEqual(reallyLong.slice(0, 19).toString(), 'yolo swag swag yolo');
3683 
3684 // Expensive reverse searches. Stress test lastIndexOf:
3685 pattern = reallyLong.slice(0, 100000); // First 1/50th of the pattern.
3686 strictEqual(reallyLong.lastIndexOf(pattern), 4751360);
3687 strictEqual(reallyLong.lastIndexOf(pattern, 4000000), 3932160);
3688 strictEqual(reallyLong.lastIndexOf(pattern, 3000000), 2949120);
3689 pattern = reallyLong.slice(100000, 200000); // Second 1/50th.
3690 strictEqual(reallyLong.lastIndexOf(pattern), 4728480);
3691 pattern = reallyLong.slice(0, 1000000); // First 1/5th.
3692 strictEqual(reallyLong.lastIndexOf(pattern), 3932160);
3693 pattern = reallyLong.slice(0, 2000000); // first 2/5ths.
3694 strictEqual(reallyLong.lastIndexOf(pattern), 0);
3695 
3696 // Test truncation of Number arguments to uint8
3697 {
3698 const buf = Buffer.from('this is a test');
3699 strictEqual(buf.indexOf(0x6973), 3);
3700 strictEqual(buf.indexOf(0x697320), 4);
3701 strictEqual(buf.indexOf(0x69732069), 2);
3702 strictEqual(buf.indexOf(0x697374657374), 0);
3703 strictEqual(buf.indexOf(0x69737374), 0);
3704 strictEqual(buf.indexOf(0x69737465), 11);
3705 strictEqual(buf.indexOf(0x69737465), 11);
3706 strictEqual(buf.indexOf(-140), 0);
3707 strictEqual(buf.indexOf(-152), 1);
3708 strictEqual(buf.indexOf(0xff), -1);
3709 strictEqual(buf.indexOf(0xffff), -1);
3710 }
3711 
3712 // Test that Uint8Array arguments are okay.
3713 {
3714 const needle = new Uint8Array([0x66, 0x6f, 0x6f]);
3715 const haystack = Buffer.from('a foo b foo');
3716 strictEqual(haystack.indexOf(needle), 2);
3717 strictEqual(haystack.lastIndexOf(needle), haystack.length - 3);
3718 }
3719 },
3720};
3721 
3722export const inheritance = {
3723 test(ctrl, env, ctx) {
3724 function T(n) {
3725 const ui8 = new Uint8Array(n);
3726 Object.setPrototypeOf(ui8, T.prototype);
3727 return ui8;
3728 }
3729 Object.setPrototypeOf(T.prototype, Buffer.prototype);
3730 Object.setPrototypeOf(T, Buffer);
3731 
3732 T.prototype.sum = function sum() {
3733 let cntr = 0;
3734 for (let i = 0; i < this.length; i++) cntr += this[i];
3735 return cntr;
3736 };
3737 
3738 const vals = [new T(4), T(4)];
3739 
3740 vals.forEach(function (t) {
3741 strictEqual(t.constructor, T);
3742 strictEqual(Object.getPrototypeOf(t), T.prototype);
3743 strictEqual(
3744 Object.getPrototypeOf(Object.getPrototypeOf(t)),
3745 Buffer.prototype
3746 );
3747 
3748 t.fill(5);
3749 let cntr = 0;
3750 for (let i = 0; i < t.length; i++) cntr += t[i];
3751 strictEqual(cntr, t.length * 5);
3752 
3753 // Check this does not throw
3754 t.toString();
3755 });
3756 },
3757};
3758 
3759export const iterator = {
3760 test(ctrl, env, ctx) {
3761 const buffer = Buffer.from([1, 2, 3, 4, 5]);
3762 let arr;
3763 let b;
3764 
3765 // Buffers should be iterable
3766 
3767 arr = [];
3768 
3769 for (b of buffer) arr.push(b);
3770 
3771 deepStrictEqual(arr, [1, 2, 3, 4, 5]);
3772 
3773 // Buffer iterators should be iterable
3774 
3775 arr = [];
3776 
3777 for (b of buffer[Symbol.iterator]()) arr.push(b);
3778 
3779 deepStrictEqual(arr, [1, 2, 3, 4, 5]);
3780 
3781 // buffer#values() should return iterator for values
3782 
3783 arr = [];
3784 
3785 for (b of buffer.values()) arr.push(b);
3786 
3787 deepStrictEqual(arr, [1, 2, 3, 4, 5]);
3788 
3789 // buffer#keys() should return iterator for keys
3790 
3791 arr = [];
3792 
3793 for (b of buffer.keys()) arr.push(b);
3794 
3795 deepStrictEqual(arr, [0, 1, 2, 3, 4]);
3796 
3797 // buffer#entries() should return iterator for entries
3798 
3799 arr = [];
3800 
3801 for (b of buffer.entries()) arr.push(b);
3802 
3803 deepStrictEqual(arr, [
3804 [0, 1],
3805 [1, 2],
3806 [2, 3],
3807 [3, 4],
3808 [4, 5],
3809 ]);
3810 },
3811};
3812 
3813export const negativeAlloc = {
3814 test(ctrl, env, ctx) {
3815 const msg = {
3816 name: 'RangeError',
3817 };
3818 
3819 // Test that negative Buffer length inputs throw errors.
3820 
3821 throws(() => Buffer(-100), msg);
3822 throws(() => Buffer(-1), msg);
3823 throws(() => Buffer(NaN), msg);
3824 
3825 throws(() => Buffer.alloc(-100), msg);
3826 throws(() => Buffer.alloc(-1), msg);
3827 throws(() => Buffer.alloc(NaN), msg);
3828 
3829 throws(() => Buffer.allocUnsafe(-100), msg);
3830 throws(() => Buffer.allocUnsafe(-1), msg);
3831 throws(() => Buffer.allocUnsafe(NaN), msg);
3832 
3833 throws(() => Buffer.allocUnsafeSlow(-100), msg);
3834 throws(() => Buffer.allocUnsafeSlow(-1), msg);
3835 throws(() => Buffer.allocUnsafeSlow(NaN), msg);
3836 
3837 throws(() => SlowBuffer(-100), msg);
3838 throws(() => SlowBuffer(-1), msg);
3839 throws(() => SlowBuffer(NaN), msg);
3840 },
3841};
3842 
3843export const overMaxLength = {
3844 test(ctrl, env, ctx) {
3845 const bufferMaxSizeMsg = {
3846 name: 'RangeError',
3847 };
3848 
3849 throws(() => Buffer((-1 >>> 0) + 2), bufferMaxSizeMsg);
3850 throws(() => SlowBuffer((-1 >>> 0) + 2), bufferMaxSizeMsg);
3851 throws(() => Buffer.alloc((-1 >>> 0) + 2), bufferMaxSizeMsg);
3852 throws(() => Buffer.allocUnsafe((-1 >>> 0) + 2), bufferMaxSizeMsg);
3853 throws(() => Buffer.allocUnsafeSlow((-1 >>> 0) + 2), bufferMaxSizeMsg);
3854 
3855 throws(() => Buffer(kMaxLength + 1), bufferMaxSizeMsg);
3856 throws(() => SlowBuffer(kMaxLength + 1), bufferMaxSizeMsg);
3857 throws(() => Buffer.alloc(kMaxLength + 1), bufferMaxSizeMsg);
3858 throws(() => Buffer.allocUnsafe(kMaxLength + 1), bufferMaxSizeMsg);
3859 throws(() => Buffer.allocUnsafeSlow(kMaxLength + 1), bufferMaxSizeMsg);
3860 
3861 // issue GH-4331
3862 throws(() => Buffer.allocUnsafe(0x100000001), bufferMaxSizeMsg);
3863 throws(() => Buffer.allocUnsafe(0xfffffffff), bufferMaxSizeMsg);
3864 },
3865};
3866 
3867export const read = {
3868 test(ctrl, env, ctx) {
3869 // Testing basic buffer read functions
3870 const buf = Buffer.from([
3871 0xa4, 0xfd, 0x48, 0xea, 0xcf, 0xff, 0xd9, 0x01, 0xde,
3872 ]);
3873 
3874 function read(buff, funx, args, expected) {
3875 strictEqual(buff[funx](...args), expected);
3876 throws(() => buff[funx](-1, args[1]), { code: 'ERR_OUT_OF_RANGE' });
3877 }
3878 
3879 // Testing basic functionality of readDoubleBE() and readDoubleLE()
3880 read(buf, 'readDoubleBE', [1], -3.1827727774563287e295);
3881 read(buf, 'readDoubleLE', [1], -6.966010051009108e144);
3882 
3883 // Testing basic functionality of readFloatBE() and readFloatLE()
3884 read(buf, 'readFloatBE', [1], -1.6691549692541768e37);
3885 read(buf, 'readFloatLE', [1], -7861303808);
3886 
3887 // Testing basic functionality of readInt8()
3888 read(buf, 'readInt8', [1], -3);
3889 
3890 // Testing basic functionality of readInt16BE() and readInt16LE()
3891 read(buf, 'readInt16BE', [1], -696);
3892 read(buf, 'readInt16LE', [1], 0x48fd);
3893 
3894 // Testing basic functionality of readInt32BE() and readInt32LE()
3895 read(buf, 'readInt32BE', [1], -45552945);
3896 read(buf, 'readInt32LE', [1], -806729475);
3897 
3898 // Testing basic functionality of readIntBE() and readIntLE()
3899 read(buf, 'readIntBE', [1, 1], -3);
3900 read(buf, 'readIntLE', [2, 1], 0x48);
3901 
3902 // Testing basic functionality of readUInt8()
3903 read(buf, 'readUInt8', [1], 0xfd);
3904 
3905 // Testing basic functionality of readUInt16BE() and readUInt16LE()
3906 read(buf, 'readUInt16BE', [2], 0x48ea);
3907 read(buf, 'readUInt16LE', [2], 0xea48);
3908 
3909 // Testing basic functionality of readUInt32BE() and readUInt32LE()
3910 read(buf, 'readUInt32BE', [1], 0xfd48eacf);
3911 read(buf, 'readUInt32LE', [1], 0xcfea48fd);
3912 
3913 // Testing basic functionality of readUIntBE() and readUIntLE()
3914 read(buf, 'readUIntBE', [2, 2], 0x48ea);
3915 read(buf, 'readUIntLE', [2, 2], 0xea48);
3916 
3917 // Error name and message
3918 const OOR_ERROR = {
3919 name: 'RangeError',
3920 };
3921 
3922 const OOB_ERROR = {
3923 name: 'RangeError',
3924 message: 'Attempt to access memory outside buffer bounds',
3925 };
3926 
3927 // Attempt to overflow buffers, similar to previous bug in array buffers
3928 throws(() => Buffer.allocUnsafe(8).readFloatBE(0xffffffff), OOR_ERROR);
3929 
3930 throws(() => Buffer.allocUnsafe(8).readFloatLE(0xffffffff), OOR_ERROR);
3931 
3932 // Ensure negative values can't get past offset
3933 throws(() => Buffer.allocUnsafe(8).readFloatBE(-1), OOR_ERROR);
3934 throws(() => Buffer.allocUnsafe(8).readFloatLE(-1), OOR_ERROR);
3935 
3936 // Offset checks
3937 {
3938 const buf = Buffer.allocUnsafe(0);
3939 
3940 throws(() => buf.readUInt8(0), OOB_ERROR);
3941 throws(() => buf.readInt8(0), OOB_ERROR);
3942 }
3943 
3944 [16, 32].forEach((bit) => {
3945 const buf = Buffer.allocUnsafe(bit / 8 - 1);
3946 [`Int${bit}B`, `Int${bit}L`, `UInt${bit}B`, `UInt${bit}L`].forEach(
3947 (fn) => {
3948 throws(() => buf[`read${fn}E`](0), OOB_ERROR);
3949 }
3950 );
3951 });
3952 
3953 [16, 32].forEach((bits) => {
3954 const buf = Buffer.from([0xff, 0xff, 0xff, 0xff]);
3955 ['LE', 'BE'].forEach((endian) => {
3956 strictEqual(
3957 buf[`readUInt${bits}${endian}`](0),
3958 0xffffffff >>> (32 - bits)
3959 );
3960 
3961 strictEqual(
3962 buf[`readInt${bits}${endian}`](0),
3963 0xffffffff >> (32 - bits)
3964 );
3965 });
3966 });
3967 },
3968};
3969 
3970export const readDouble = {
3971 test(ctrl, env, ctx) {
3972 // Test (64 bit) double
3973 const buffer = Buffer.allocUnsafe(8);
3974 
3975 buffer[0] = 0x55;
3976 buffer[1] = 0x55;
3977 buffer[2] = 0x55;
3978 buffer[3] = 0x55;
3979 buffer[4] = 0x55;
3980 buffer[5] = 0x55;
3981 buffer[6] = 0xd5;
3982 buffer[7] = 0x3f;
3983 strictEqual(buffer.readDoubleBE(0), 1.1945305291680097e103);
3984 strictEqual(buffer.readDoubleLE(0), 0.3333333333333333);
3985 
3986 buffer[0] = 1;
3987 buffer[1] = 0;
3988 buffer[2] = 0;
3989 buffer[3] = 0;
3990 buffer[4] = 0;
3991 buffer[5] = 0;
3992 buffer[6] = 0xf0;
3993 buffer[7] = 0x3f;
3994 strictEqual(buffer.readDoubleBE(0), 7.291122019655968e-304);
3995 strictEqual(buffer.readDoubleLE(0), 1.0000000000000002);
3996 
3997 buffer[0] = 2;
3998 strictEqual(buffer.readDoubleBE(0), 4.778309726801735e-299);
3999 strictEqual(buffer.readDoubleLE(0), 1.0000000000000004);
4000 
4001 buffer[0] = 1;
4002 buffer[6] = 0;
4003 buffer[7] = 0;
4004 // eslint-disable-next-line no-loss-of-precision
4005 strictEqual(buffer.readDoubleBE(0), 7.291122019556398e-304);
4006 strictEqual(buffer.readDoubleLE(0), 5e-324);
4007 
4008 buffer[0] = 0xff;
4009 buffer[1] = 0xff;
4010 buffer[2] = 0xff;
4011 buffer[3] = 0xff;
4012 buffer[4] = 0xff;
4013 buffer[5] = 0xff;
4014 buffer[6] = 0x0f;
4015 buffer[7] = 0x00;
4016 ok(Number.isNaN(buffer.readDoubleBE(0)));
4017 strictEqual(buffer.readDoubleLE(0), 2.225073858507201e-308);
4018 
4019 buffer[6] = 0xef;
4020 buffer[7] = 0x7f;
4021 ok(Number.isNaN(buffer.readDoubleBE(0)));
4022 strictEqual(buffer.readDoubleLE(0), 1.7976931348623157e308);
4023 
4024 buffer[0] = 0;
4025 buffer[1] = 0;
4026 buffer[2] = 0;
4027 buffer[3] = 0;
4028 buffer[4] = 0;
4029 buffer[5] = 0;
4030 buffer[6] = 0xf0;
4031 buffer[7] = 0x3f;
4032 strictEqual(buffer.readDoubleBE(0), 3.03865e-319);
4033 strictEqual(buffer.readDoubleLE(0), 1);
4034 
4035 buffer[6] = 0;
4036 buffer[7] = 0x40;
4037 strictEqual(buffer.readDoubleBE(0), 3.16e-322);
4038 strictEqual(buffer.readDoubleLE(0), 2);
4039 
4040 buffer[7] = 0xc0;
4041 strictEqual(buffer.readDoubleBE(0), 9.5e-322);
4042 strictEqual(buffer.readDoubleLE(0), -2);
4043 
4044 buffer[6] = 0x10;
4045 buffer[7] = 0;
4046 strictEqual(buffer.readDoubleBE(0), 2.0237e-320);
4047 strictEqual(buffer.readDoubleLE(0), 2.2250738585072014e-308);
4048 
4049 buffer[6] = 0;
4050 strictEqual(buffer.readDoubleBE(0), 0);
4051 strictEqual(buffer.readDoubleLE(0), 0);
4052 ok(1 / buffer.readDoubleLE(0) >= 0);
4053 
4054 buffer[7] = 0x80;
4055 strictEqual(buffer.readDoubleBE(0), 6.3e-322);
4056 strictEqual(buffer.readDoubleLE(0), -0);
4057 ok(1 / buffer.readDoubleLE(0) < 0);
4058 
4059 buffer[6] = 0xf0;
4060 buffer[7] = 0x7f;
4061 strictEqual(buffer.readDoubleBE(0), 3.0418e-319);
4062 strictEqual(buffer.readDoubleLE(0), Infinity);
4063 
4064 buffer[7] = 0xff;
4065 strictEqual(buffer.readDoubleBE(0), 3.04814e-319);
4066 strictEqual(buffer.readDoubleLE(0), -Infinity);
4067 
4068 ['readDoubleLE', 'readDoubleBE'].forEach((fn) => {
4069 // Verify that default offset works fine.
4070 buffer[fn](undefined);
4071 buffer[fn]();
4072 
4073 ['', '0', null, {}, [], () => {}, true, false].forEach((off) => {
4074 throws(() => buffer[fn](off), { code: 'ERR_INVALID_ARG_TYPE' });
4075 });
4076 
4077 [Infinity, -1, 1].forEach((offset) => {
4078 throws(() => buffer[fn](offset), {
4079 code: 'ERR_OUT_OF_RANGE',
4080 name: 'RangeError',
4081 });
4082 });
4083 
4084 throws(() => Buffer.alloc(1)[fn](1), {
4085 code: 'ERR_BUFFER_OUT_OF_BOUNDS',
4086 name: 'RangeError',
4087 message: 'Attempt to access memory outside buffer bounds',
4088 });
4089 
4090 [NaN, 1.01].forEach((offset) => {
4091 throws(() => buffer[fn](offset), {
4092 code: 'ERR_OUT_OF_RANGE',
4093 name: 'RangeError',
4094 message:
4095 'The value of "offset" is out of range. ' +
4096 `It must be an integer. Received ${offset}`,
4097 });
4098 });
4099 });
4100 },
4101};
4102 
4103export const readFloat = {
4104 test(ctrl, env, ctx) {
4105 // Test 32 bit float
4106 const buffer = Buffer.alloc(4);
4107 
4108 buffer[0] = 0;
4109 buffer[1] = 0;
4110 buffer[2] = 0x80;
4111 buffer[3] = 0x3f;
4112 strictEqual(buffer.readFloatBE(0), 4.600602988224807e-41);
4113 strictEqual(buffer.readFloatLE(0), 1);
4114 
4115 buffer[0] = 0;
4116 buffer[1] = 0;
4117 buffer[2] = 0;
4118 buffer[3] = 0xc0;
4119 strictEqual(buffer.readFloatBE(0), 2.6904930515036488e-43);
4120 strictEqual(buffer.readFloatLE(0), -2);
4121 
4122 buffer[0] = 0xff;
4123 buffer[1] = 0xff;
4124 buffer[2] = 0x7f;
4125 buffer[3] = 0x7f;
4126 ok(Number.isNaN(buffer.readFloatBE(0)));
4127 strictEqual(buffer.readFloatLE(0), 3.4028234663852886e38);
4128 
4129 buffer[0] = 0xab;
4130 buffer[1] = 0xaa;
4131 buffer[2] = 0xaa;
4132 buffer[3] = 0x3e;
4133 strictEqual(buffer.readFloatBE(0), -1.2126478207002966e-12);
4134 strictEqual(buffer.readFloatLE(0), 0.3333333432674408);
4135 
4136 buffer[0] = 0;
4137 buffer[1] = 0;
4138 buffer[2] = 0;
4139 buffer[3] = 0;
4140 strictEqual(buffer.readFloatBE(0), 0);
4141 strictEqual(buffer.readFloatLE(0), 0);
4142 ok(1 / buffer.readFloatLE(0) >= 0);
4143 
4144 buffer[3] = 0x80;
4145 strictEqual(buffer.readFloatBE(0), 1.793662034335766e-43);
4146 strictEqual(buffer.readFloatLE(0), -0);
4147 ok(1 / buffer.readFloatLE(0) < 0);
4148 
4149 buffer[0] = 0;
4150 buffer[1] = 0;
4151 buffer[2] = 0x80;
4152 buffer[3] = 0x7f;
4153 strictEqual(buffer.readFloatBE(0), 4.609571298396486e-41);
4154 strictEqual(buffer.readFloatLE(0), Infinity);
4155 
4156 buffer[0] = 0;
4157 buffer[1] = 0;
4158 buffer[2] = 0x80;
4159 buffer[3] = 0xff;
4160 strictEqual(buffer.readFloatBE(0), 4.627507918739843e-41);
4161 strictEqual(buffer.readFloatLE(0), -Infinity);
4162 
4163 ['readFloatLE', 'readFloatBE'].forEach((fn) => {
4164 // Verify that default offset works fine.
4165 buffer[fn](undefined);
4166 buffer[fn]();
4167 
4168 ['', '0', null, {}, [], () => {}, true, false].forEach((off) => {
4169 throws(() => buffer[fn](off), { code: 'ERR_INVALID_ARG_TYPE' });
4170 });
4171 
4172 [Infinity, -1, 1].forEach((offset) => {
4173 throws(() => buffer[fn](offset), {
4174 code: 'ERR_OUT_OF_RANGE',
4175 name: 'RangeError',
4176 });
4177 });
4178 
4179 throws(() => Buffer.alloc(1)[fn](1), {
4180 code: 'ERR_BUFFER_OUT_OF_BOUNDS',
4181 name: 'RangeError',
4182 message: 'Attempt to access memory outside buffer bounds',
4183 });
4184 
4185 [NaN, 1.01].forEach((offset) => {
4186 throws(() => buffer[fn](offset), {
4187 code: 'ERR_OUT_OF_RANGE',
4188 name: 'RangeError',
4189 message:
4190 'The value of "offset" is out of range. ' +
4191 `It must be an integer. Received ${offset}`,
4192 });
4193 });
4194 });
4195 },
4196};
4197 
4198export const readInt = {
4199 test(ctrl, env, ctx) {
4200 // Test OOB
4201 {
4202 const buffer = Buffer.alloc(4);
4203 
4204 ['Int8', 'Int16BE', 'Int16LE', 'Int32BE', 'Int32LE'].forEach((fn) => {
4205 // Verify that default offset works fine.
4206 buffer[`read${fn}`](undefined);
4207 buffer[`read${fn}`]();
4208 
4209 ['', '0', null, {}, [], () => {}, true, false].forEach((o) => {
4210 throws(() => buffer[`read${fn}`](o), {
4211 code: 'ERR_INVALID_ARG_TYPE',
4212 name: 'TypeError',
4213 });
4214 });
4215 
4216 [Infinity, -1, -4294967295].forEach((offset) => {
4217 throws(() => buffer[`read${fn}`](offset), {
4218 code: 'ERR_OUT_OF_RANGE',
4219 name: 'RangeError',
4220 });
4221 });
4222 
4223 [NaN, 1.01].forEach((offset) => {
4224 throws(() => buffer[`read${fn}`](offset), {
4225 code: 'ERR_OUT_OF_RANGE',
4226 name: 'RangeError',
4227 });
4228 });
4229 });
4230 }
4231 
4232 // Test 8 bit signed integers
4233 {
4234 const data = Buffer.from([0x23, 0xab, 0x7c, 0xef]);
4235 
4236 strictEqual(data.readInt8(0), 0x23);
4237 
4238 data[0] = 0xff;
4239 strictEqual(data.readInt8(0), -1);
4240 
4241 data[0] = 0x87;
4242 strictEqual(data.readInt8(0), -121);
4243 strictEqual(data.readInt8(1), -85);
4244 strictEqual(data.readInt8(2), 124);
4245 strictEqual(data.readInt8(3), -17);
4246 }
4247 
4248 // Test 16 bit integers
4249 {
4250 const buffer = Buffer.from([0x16, 0x79, 0x65, 0x6e, 0x69, 0x78]);
4251 
4252 strictEqual(buffer.readInt16BE(0), 0x1679);
4253 strictEqual(buffer.readInt16LE(0), 0x7916);
4254 
4255 buffer[0] = 0xff;
4256 buffer[1] = 0x80;
4257 strictEqual(buffer.readInt16BE(0), -128);
4258 strictEqual(buffer.readInt16LE(0), -32513);
4259 
4260 buffer[0] = 0x77;
4261 buffer[1] = 0x65;
4262 strictEqual(buffer.readInt16BE(0), 0x7765);
4263 strictEqual(buffer.readInt16BE(1), 0x6565);
4264 strictEqual(buffer.readInt16BE(2), 0x656e);
4265 strictEqual(buffer.readInt16BE(3), 0x6e69);
4266 strictEqual(buffer.readInt16BE(4), 0x6978);
4267 strictEqual(buffer.readInt16LE(0), 0x6577);
4268 strictEqual(buffer.readInt16LE(1), 0x6565);
4269 strictEqual(buffer.readInt16LE(2), 0x6e65);
4270 strictEqual(buffer.readInt16LE(3), 0x696e);
4271 strictEqual(buffer.readInt16LE(4), 0x7869);
4272 }
4273 
4274 // Test 32 bit integers
4275 {
4276 const buffer = Buffer.from([0x43, 0x53, 0x16, 0x79, 0x36, 0x17]);
4277 
4278 strictEqual(buffer.readInt32BE(0), 0x43531679);
4279 strictEqual(buffer.readInt32LE(0), 0x79165343);
4280 
4281 buffer[0] = 0xff;
4282 buffer[1] = 0xfe;
4283 buffer[2] = 0xef;
4284 buffer[3] = 0xfa;
4285 strictEqual(buffer.readInt32BE(0), -69638);
4286 strictEqual(buffer.readInt32LE(0), -84934913);
4287 
4288 buffer[0] = 0x42;
4289 buffer[1] = 0xc3;
4290 buffer[2] = 0x95;
4291 buffer[3] = 0xa9;
4292 strictEqual(buffer.readInt32BE(0), 0x42c395a9);
4293 strictEqual(buffer.readInt32BE(1), -1013601994);
4294 strictEqual(buffer.readInt32BE(2), -1784072681);
4295 strictEqual(buffer.readInt32LE(0), -1449802942);
4296 strictEqual(buffer.readInt32LE(1), 917083587);
4297 strictEqual(buffer.readInt32LE(2), 389458325);
4298 }
4299 
4300 // Test Int
4301 {
4302 const buffer = Buffer.from([
4303 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
4304 ]);
4305 
4306 strictEqual(buffer.readIntLE(0, 1), 0x01);
4307 strictEqual(buffer.readIntBE(0, 1), 0x01);
4308 strictEqual(buffer.readIntLE(0, 3), 0x030201);
4309 strictEqual(buffer.readIntBE(0, 3), 0x010203);
4310 strictEqual(buffer.readIntLE(0, 5), 0x0504030201);
4311 strictEqual(buffer.readIntBE(0, 5), 0x0102030405);
4312 strictEqual(buffer.readIntLE(0, 6), 0x060504030201);
4313 strictEqual(buffer.readIntBE(0, 6), 0x010203040506);
4314 strictEqual(buffer.readIntLE(1, 6), 0x070605040302);
4315 strictEqual(buffer.readIntBE(1, 6), 0x020304050607);
4316 strictEqual(buffer.readIntLE(2, 6), 0x080706050403);
4317 strictEqual(buffer.readIntBE(2, 6), 0x030405060708);
4318 
4319 // Check byteLength.
4320 ['readIntBE', 'readIntLE'].forEach((fn) => {
4321 ['', '0', null, {}, [], () => {}, true, false, undefined].forEach(
4322 (len) => {
4323 throws(() => buffer[fn](0, len), { name: 'RangeError' });
4324 }
4325 );
4326 
4327 [Infinity, -1].forEach((byteLength) => {
4328 throws(() => buffer[fn](0, byteLength), {
4329 name: 'RangeError',
4330 });
4331 });
4332 
4333 [NaN, 1.01].forEach((byteLength) => {
4334 throws(() => buffer[fn](0, byteLength), {
4335 name: 'RangeError',
4336 });
4337 });
4338 });
4339 
4340 // Test 1 to 6 bytes.
4341 for (let i = 1; i <= 6; i++) {
4342 ['readIntBE', 'readIntLE'].forEach((fn) => {
4343 ['', '0', null, {}, [], () => {}, true, false, undefined].forEach(
4344 (o) => {
4345 throws(() => buffer[fn](o, i), {
4346 name: 'TypeError',
4347 });
4348 }
4349 );
4350 
4351 [Infinity, -1, -4294967295].forEach((offset) => {
4352 throws(() => buffer[fn](offset, i), {
4353 name: 'RangeError',
4354 });
4355 });
4356 
4357 [NaN, 1.01].forEach((offset) => {
4358 throws(() => buffer[fn](offset, i), {
4359 name: 'RangeError',
4360 });
4361 });
4362 });
4363 }
4364 }
4365 },
4366};
4367 
4368export const readUint = {
4369 test(ctrl, env, ctx) {
4370 // Test OOB
4371 {
4372 const buffer = Buffer.alloc(4);
4373 
4374 ['UInt8', 'UInt16BE', 'UInt16LE', 'UInt32BE', 'UInt32LE'].forEach(
4375 (fn) => {
4376 // Verify that default offset works fine.
4377 buffer[`read${fn}`](undefined);
4378 buffer[`read${fn}`]();
4379 
4380 ['', '0', null, {}, [], () => {}, true, false].forEach((o) => {
4381 throws(() => buffer[`read${fn}`](o), {
4382 code: 'ERR_INVALID_ARG_TYPE',
4383 name: 'TypeError',
4384 });
4385 });
4386 
4387 [Infinity, -1, -4294967295].forEach((offset) => {
4388 throws(() => buffer[`read${fn}`](offset), {
4389 code: 'ERR_OUT_OF_RANGE',
4390 name: 'RangeError',
4391 });
4392 });
4393 
4394 [NaN, 1.01].forEach((offset) => {
4395 throws(() => buffer[`read${fn}`](offset), {
4396 code: 'ERR_OUT_OF_RANGE',
4397 name: 'RangeError',
4398 });
4399 });
4400 }
4401 );
4402 }
4403 
4404 // Test 8 bit unsigned integers
4405 {
4406 const data = Buffer.from([0xff, 0x2a, 0x2a, 0x2a]);
4407 strictEqual(data.readUInt8(0), 255);
4408 strictEqual(data.readUInt8(1), 42);
4409 strictEqual(data.readUInt8(2), 42);
4410 strictEqual(data.readUInt8(3), 42);
4411 }
4412 
4413 // Test 16 bit unsigned integers
4414 {
4415 const data = Buffer.from([0x00, 0x2a, 0x42, 0x3f]);
4416 strictEqual(data.readUInt16BE(0), 0x2a);
4417 strictEqual(data.readUInt16BE(1), 0x2a42);
4418 strictEqual(data.readUInt16BE(2), 0x423f);
4419 strictEqual(data.readUInt16LE(0), 0x2a00);
4420 strictEqual(data.readUInt16LE(1), 0x422a);
4421 strictEqual(data.readUInt16LE(2), 0x3f42);
4422 
4423 data[0] = 0xfe;
4424 data[1] = 0xfe;
4425 strictEqual(data.readUInt16BE(0), 0xfefe);
4426 strictEqual(data.readUInt16LE(0), 0xfefe);
4427 }
4428 
4429 // Test 32 bit unsigned integers
4430 {
4431 const data = Buffer.from([0x32, 0x65, 0x42, 0x56, 0x23, 0xff]);
4432 strictEqual(data.readUInt32BE(0), 0x32654256);
4433 strictEqual(data.readUInt32BE(1), 0x65425623);
4434 strictEqual(data.readUInt32BE(2), 0x425623ff);
4435 strictEqual(data.readUInt32LE(0), 0x56426532);
4436 strictEqual(data.readUInt32LE(1), 0x23564265);
4437 strictEqual(data.readUInt32LE(2), 0xff235642);
4438 }
4439 
4440 // Test UInt
4441 {
4442 const buffer = Buffer.from([
4443 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
4444 ]);
4445 
4446 strictEqual(buffer.readUIntLE(0, 1), 0x01);
4447 strictEqual(buffer.readUIntBE(0, 1), 0x01);
4448 strictEqual(buffer.readUIntLE(0, 3), 0x030201);
4449 strictEqual(buffer.readUIntBE(0, 3), 0x010203);
4450 strictEqual(buffer.readUIntLE(0, 5), 0x0504030201);
4451 strictEqual(buffer.readUIntBE(0, 5), 0x0102030405);
4452 strictEqual(buffer.readUIntLE(0, 6), 0x060504030201);
4453 strictEqual(buffer.readUIntBE(0, 6), 0x010203040506);
4454 strictEqual(buffer.readUIntLE(1, 6), 0x070605040302);
4455 strictEqual(buffer.readUIntBE(1, 6), 0x020304050607);
4456 strictEqual(buffer.readUIntLE(2, 6), 0x080706050403);
4457 strictEqual(buffer.readUIntBE(2, 6), 0x030405060708);
4458 
4459 // Check byteLength.
4460 ['readUIntBE', 'readUIntLE'].forEach((fn) => {
4461 ['', '0', null, {}, [], () => {}, true, false, undefined].forEach(
4462 (len) => {
4463 throws(() => buffer[fn](0, len), { name: 'RangeError' });
4464 }
4465 );
4466 
4467 [Infinity, -1].forEach((byteLength) => {
4468 throws(() => buffer[fn](0, byteLength), {
4469 name: 'RangeError',
4470 });
4471 });
4472 
4473 [NaN, 1.01].forEach((byteLength) => {
4474 throws(() => buffer[fn](0, byteLength), {
4475 name: 'RangeError',
4476 });
4477 });
4478 });
4479 
4480 // Test 1 to 6 bytes.
4481 for (let i = 1; i <= 6; i++) {
4482 ['readUIntBE', 'readUIntLE'].forEach((fn) => {
4483 ['', '0', null, {}, [], () => {}, true, false, undefined].forEach(
4484 (o) => {
4485 throws(() => buffer[fn](o, i), {
4486 name: 'TypeError',
4487 });
4488 }
4489 );
4490 
4491 [Infinity, -1, -4294967295].forEach((offset) => {
4492 throws(() => buffer[fn](offset, i), {
4493 name: 'RangeError',
4494 });
4495 });
4496 
4497 [NaN, 1.01].forEach((offset) => {
4498 throws(() => buffer[fn](offset, i), {
4499 name: 'RangeError',
4500 });
4501 });
4502 });
4503 }
4504 }
4505 },
4506};
4507 
4508export const sharedArrayBuffer = {
4509 test(ctrl, env, ctx) {
4510 const sab = new SharedArrayBuffer(24);
4511 const arr1 = new Uint16Array(sab);
4512 const arr2 = new Uint16Array(12);
4513 arr2[0] = 5000;
4514 arr1[0] = 5000;
4515 arr1[1] = 4000;
4516 arr2[1] = 4000;
4517 
4518 const arr_buf = Buffer.from(arr1.buffer);
4519 const ar_buf = Buffer.from(arr2.buffer);
4520 
4521 deepStrictEqual(arr_buf, ar_buf);
4522 
4523 arr1[1] = 6000;
4524 arr2[1] = 6000;
4525 
4526 deepStrictEqual(arr_buf, ar_buf);
4527 
4528 // Checks for calling Buffer.byteLength on a SharedArrayBuffer.
4529 strictEqual(Buffer.byteLength(sab), sab.byteLength);
4530 
4531 Buffer.from({ buffer: sab }); // Should not throw.
4532 },
4533};
4534 
4535export const slice = {
4536 test(ctrl, env, ctx) {
4537 strictEqual(Buffer.from('hello', 'utf8').slice(0, 0).length, 0);
4538 strictEqual(Buffer('hello', 'utf8').slice(0, 0).length, 0);
4539 
4540 const buf = Buffer.from('0123456789', 'utf8');
4541 const expectedSameBufs = [
4542 [buf.slice(-10, 10), Buffer.from('0123456789', 'utf8')],
4543 [buf.slice(-20, 10), Buffer.from('0123456789', 'utf8')],
4544 [buf.slice(-20, -10), Buffer.from('', 'utf8')],
4545 [buf.slice(), Buffer.from('0123456789', 'utf8')],
4546 [buf.slice(0), Buffer.from('0123456789', 'utf8')],
4547 [buf.slice(0, 0), Buffer.from('', 'utf8')],
4548 [buf.slice(undefined), Buffer.from('0123456789', 'utf8')],
4549 [buf.slice('foobar'), Buffer.from('0123456789', 'utf8')],
4550 [buf.slice(undefined, undefined), Buffer.from('0123456789', 'utf8')],
4551 [buf.slice(2), Buffer.from('23456789', 'utf8')],
4552 [buf.slice(5), Buffer.from('56789', 'utf8')],
4553 [buf.slice(10), Buffer.from('', 'utf8')],
4554 [buf.slice(5, 8), Buffer.from('567', 'utf8')],
4555 [buf.slice(8, -1), Buffer.from('8', 'utf8')],
4556 [buf.slice(-10), Buffer.from('0123456789', 'utf8')],
4557 [buf.slice(0, -9), Buffer.from('0', 'utf8')],
4558 [buf.slice(0, -10), Buffer.from('', 'utf8')],
4559 [buf.slice(0, -1), Buffer.from('012345678', 'utf8')],
4560 [buf.slice(2, -2), Buffer.from('234567', 'utf8')],
4561 [buf.slice(0, 65536), Buffer.from('0123456789', 'utf8')],
4562 [buf.slice(65536, 0), Buffer.from('', 'utf8')],
4563 [buf.slice(-5, -8), Buffer.from('', 'utf8')],
4564 [buf.slice(-5, -3), Buffer.from('56', 'utf8')],
4565 [buf.slice(-10, 10), Buffer.from('0123456789', 'utf8')],
4566 [buf.slice('0', '1'), Buffer.from('0', 'utf8')],
4567 [buf.slice('-5', '10'), Buffer.from('56789', 'utf8')],
4568 [buf.slice('-10', '10'), Buffer.from('0123456789', 'utf8')],
4569 [buf.slice('-10', '-5'), Buffer.from('01234', 'utf8')],
4570 [buf.slice('-10', '-0'), Buffer.from('', 'utf8')],
4571 [buf.slice('111'), Buffer.from('', 'utf8')],
4572 [buf.slice('0', '-111'), Buffer.from('', 'utf8')],
4573 ];
4574 
4575 for (let i = 0, s = buf.toString(); i < buf.length; ++i) {
4576 expectedSameBufs.push(
4577 [buf.slice(i), Buffer.from(s.slice(i))],
4578 [buf.slice(0, i), Buffer.from(s.slice(0, i))],
4579 [buf.slice(-i), Buffer.from(s.slice(-i))],
4580 [buf.slice(0, -i), Buffer.from(s.slice(0, -i))]
4581 );
4582 }
4583 
4584 expectedSameBufs.forEach(([buf1, buf2]) => {
4585 strictEqual(Buffer.compare(buf1, buf2), 0);
4586 });
4587 
4588 const utf16Buf = Buffer.from('0123456789', 'utf16le');
4589 deepStrictEqual(utf16Buf.slice(0, 6), Buffer.from('012', 'utf16le'));
4590 // Try to slice a zero length Buffer.
4591 // See https://github.com/joyent/node/issues/5881
4592 strictEqual(Buffer.alloc(0).slice(0, 1).length, 0);
4593 
4594 {
4595 // Single argument slice
4596 strictEqual(
4597 Buffer.from('abcde', 'utf8').slice(1).toString('utf8'),
4598 'bcde'
4599 );
4600 }
4601 
4602 // slice(0,0).length === 0
4603 strictEqual(Buffer.from('hello', 'utf8').slice(0, 0).length, 0);
4604 
4605 {
4606 // Regression tests for https://github.com/nodejs/node/issues/9096
4607 const buf = Buffer.from('abcd', 'utf8');
4608 strictEqual(buf.slice(buf.length / 3).toString('utf8'), 'bcd');
4609 strictEqual(buf.slice(buf.length / 3, buf.length).toString(), 'bcd');
4610 }
4611 
4612 {
4613 const buf = Buffer.from('abcdefg', 'utf8');
4614 strictEqual(
4615 buf.slice(-(-1 >>> 0) - 1).toString('utf8'),
4616 buf.toString('utf8')
4617 );
4618 }
4619 
4620 {
4621 const buf = Buffer.from('abc', 'utf8');
4622 strictEqual(buf.slice(-0.5).toString('utf8'), buf.toString('utf8'));
4623 }
4624 
4625 {
4626 const buf = Buffer.from([
4627 1, 29, 0, 0, 1, 143, 216, 162, 92, 254, 248, 63, 0, 0, 0, 18, 184, 6, 0,
4628 175, 29, 0, 8, 11, 1, 0, 0,
4629 ]);
4630 const chunk1 = Buffer.from([
4631 1, 29, 0, 0, 1, 143, 216, 162, 92, 254, 248, 63, 0,
4632 ]);
4633 const chunk2 = Buffer.from([
4634 0, 0, 18, 184, 6, 0, 175, 29, 0, 8, 11, 1, 0, 0,
4635 ]);
4636 const middle = buf.length / 2;
4637 
4638 deepStrictEqual(buf.slice(0, middle), chunk1);
4639 deepStrictEqual(buf.slice(middle), chunk2);
4640 }
4641 },
4642};
4643 
4644export const swap = {
4645 test(ctrl, env, ctx) {
4646 // Test buffers small enough to use the JS implementation
4647 {
4648 const buf = Buffer.from([
4649 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
4650 0x0d, 0x0e, 0x0f, 0x10,
4651 ]);
4652 
4653 strictEqual(buf, buf.swap16());
4654 deepStrictEqual(
4655 buf,
4656 Buffer.from([
4657 0x02, 0x01, 0x04, 0x03, 0x06, 0x05, 0x08, 0x07, 0x0a, 0x09, 0x0c,
4658 0x0b, 0x0e, 0x0d, 0x10, 0x0f,
4659 ])
4660 );
4661 buf.swap16(); // restore
4662 
4663 strictEqual(buf, buf.swap32());
4664 deepStrictEqual(
4665 buf,
4666 Buffer.from([
4667 0x04, 0x03, 0x02, 0x01, 0x08, 0x07, 0x06, 0x05, 0x0c, 0x0b, 0x0a,
4668 0x09, 0x10, 0x0f, 0x0e, 0x0d,
4669 ])
4670 );
4671 buf.swap32(); // restore
4672 
4673 strictEqual(buf, buf.swap64());
4674 deepStrictEqual(
4675 buf,
4676 Buffer.from([
4677 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x10, 0x0f, 0x0e,
4678 0x0d, 0x0c, 0x0b, 0x0a, 0x09,
4679 ])
4680 );
4681 }
4682 
4683 // Operates in-place
4684 {
4685 const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7]);
4686 buf.slice(1, 5).swap32();
4687 deepStrictEqual(buf, Buffer.from([0x1, 0x5, 0x4, 0x3, 0x2, 0x6, 0x7]));
4688 buf.slice(1, 5).swap16();
4689 deepStrictEqual(buf, Buffer.from([0x1, 0x4, 0x5, 0x2, 0x3, 0x6, 0x7]));
4690 
4691 // Length assertions
4692 const re16 = /Buffer size must be a multiple of 16-bits/;
4693 const re32 = /Buffer size must be a multiple of 32-bits/;
4694 const re64 = /Buffer size must be a multiple of 64-bits/;
4695 
4696 throws(() => Buffer.from(buf).swap16(), re16);
4697 throws(() => Buffer.alloc(1025).swap16(), re16);
4698 throws(() => Buffer.from(buf).swap32(), re32);
4699 throws(() => buf.slice(1, 3).swap32(), re32);
4700 throws(() => Buffer.alloc(1025).swap32(), re32);
4701 throws(() => buf.slice(1, 3).swap64(), re64);
4702 throws(() => Buffer.alloc(1025).swap64(), re64);
4703 }
4704 
4705 {
4706 const buf = Buffer.from([
4707 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
4708 0x0d, 0x0e, 0x0f, 0x10, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
4709 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
4710 ]);
4711 
4712 buf.slice(2, 18).swap64();
4713 
4714 deepStrictEqual(
4715 buf,
4716 Buffer.from([
4717 0x01, 0x02, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02,
4718 0x01, 0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x03, 0x04, 0x05, 0x06,
4719 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
4720 ])
4721 );
4722 }
4723 
4724 // Force use of native code (Buffer size above threshold limit for js impl)
4725 {
4726 const bufData = new Uint32Array(256).fill(0x04030201);
4727 const buf = Buffer.from(bufData.buffer, bufData.byteOffset);
4728 const otherBufData = new Uint32Array(256).fill(0x03040102);
4729 const otherBuf = Buffer.from(
4730 otherBufData.buffer,
4731 otherBufData.byteOffset
4732 );
4733 buf.swap16();
4734 deepStrictEqual(buf, otherBuf);
4735 }
4736 
4737 {
4738 const bufData = new Uint32Array(256).fill(0x04030201);
4739 const buf = Buffer.from(bufData.buffer);
4740 const otherBufData = new Uint32Array(256).fill(0x01020304);
4741 const otherBuf = Buffer.from(
4742 otherBufData.buffer,
4743 otherBufData.byteOffset
4744 );
4745 buf.swap32();
4746 deepStrictEqual(buf, otherBuf);
4747 }
4748 
4749 {
4750 const bufData = new Uint8Array(256 * 8);
4751 const otherBufData = new Uint8Array(256 * 8);
4752 for (let i = 0; i < bufData.length; i++) {
4753 bufData[i] = i % 8;
4754 otherBufData[otherBufData.length - i - 1] = i % 8;
4755 }
4756 const buf = Buffer.from(bufData.buffer, bufData.byteOffset);
4757 const otherBuf = Buffer.from(
4758 otherBufData.buffer,
4759 otherBufData.byteOffset
4760 );
4761 buf.swap64();
4762 deepStrictEqual(buf, otherBuf);
4763 }
4764 
4765 // Test native code with buffers that are not memory-aligned
4766 {
4767 const bufData = new Uint8Array(256 * 8);
4768 const otherBufData = new Uint8Array(256 * 8 - 2);
4769 for (let i = 0; i < bufData.length; i++) {
4770 bufData[i] = i % 2;
4771 }
4772 for (let i = 1; i < otherBufData.length; i++) {
4773 otherBufData[otherBufData.length - i] = (i + 1) % 2;
4774 }
4775 const buf = Buffer.from(bufData.buffer, bufData.byteOffset);
4776 // 0|1 0|1 0|1...
4777 const otherBuf = Buffer.from(
4778 otherBufData.buffer,
4779 otherBufData.byteOffset
4780 );
4781 // 0|0 1|0 1|0...
4782 
4783 buf.slice(1, buf.length - 1).swap16();
4784 deepStrictEqual(buf.slice(0, otherBuf.length), otherBuf);
4785 }
4786 
4787 {
4788 const bufData = new Uint8Array(256 * 8);
4789 const otherBufData = new Uint8Array(256 * 8 - 4);
4790 for (let i = 0; i < bufData.length; i++) {
4791 bufData[i] = i % 4;
4792 }
4793 for (let i = 1; i < otherBufData.length; i++) {
4794 otherBufData[otherBufData.length - i] = (i + 1) % 4;
4795 }
4796 const buf = Buffer.from(bufData.buffer, bufData.byteOffset);
4797 // 0|1 2 3 0|1 2 3...
4798 const otherBuf = Buffer.from(
4799 otherBufData.buffer,
4800 otherBufData.byteOffset
4801 );
4802 // 0|0 3 2 1|0 3 2...
4803 
4804 buf.slice(1, buf.length - 3).swap32();
4805 deepStrictEqual(buf.slice(0, otherBuf.length), otherBuf);
4806 }
4807 
4808 {
4809 const bufData = new Uint8Array(256 * 8);
4810 const otherBufData = new Uint8Array(256 * 8 - 8);
4811 for (let i = 0; i < bufData.length; i++) {
4812 bufData[i] = i % 8;
4813 }
4814 for (let i = 1; i < otherBufData.length; i++) {
4815 otherBufData[otherBufData.length - i] = (i + 1) % 8;
4816 }
4817 const buf = Buffer.from(bufData.buffer, bufData.byteOffset);
4818 // 0|1 2 3 4 5 6 7 0|1 2 3 4...
4819 const otherBuf = Buffer.from(
4820 otherBufData.buffer,
4821 otherBufData.byteOffset
4822 );
4823 // 0|0 7 6 5 4 3 2 1|0 7 6 5...
4824 
4825 buf.slice(1, buf.length - 7).swap64();
4826 deepStrictEqual(buf.slice(0, otherBuf.length), otherBuf);
4827 }
4828 },
4829};
4830 
4831export const json = {
4832 test(ctrl, env, ctx) {
4833 {
4834 strictEqual(
4835 JSON.stringify(Buffer.alloc(0)),
4836 '{"type":"Buffer","data":[]}'
4837 );
4838 strictEqual(
4839 JSON.stringify(Buffer.from([1, 2, 3, 4])),
4840 '{"type":"Buffer","data":[1,2,3,4]}'
4841 );
4842 }
4843 
4844 // issue GH-7849
4845 {
4846 const buf = Buffer.from('test');
4847 const json = JSON.stringify(buf);
4848 const obj = JSON.parse(json);
4849 const copy = Buffer.from(obj);
4850 
4851 deepStrictEqual(buf, copy);
4852 }
4853 
4854 // GH-5110
4855 {
4856 const buffer = Buffer.from('test');
4857 const string = JSON.stringify(buffer);
4858 
4859 strictEqual(string, '{"type":"Buffer","data":[116,101,115,116]}');
4860 
4861 function receiver(key, value) {
4862 return value && value.type === 'Buffer'
4863 ? Buffer.from(value.data)
4864 : value;
4865 }
4866 
4867 deepStrictEqual(buffer, JSON.parse(string, receiver));
4868 }
4869 },
4870};
4871 
4872export const writeUint8 = {
4873 test(ctrl, env, ctx) {
4874 {
4875 // OOB
4876 const data = Buffer.alloc(8);
4877 ['UInt8', 'UInt16BE', 'UInt16LE', 'UInt32BE', 'UInt32LE'].forEach(
4878 (fn) => {
4879 // Verify that default offset works fine.
4880 data[`write${fn}`](23, undefined);
4881 data[`write${fn}`](23);
4882 
4883 ['', '0', null, {}, [], () => {}, true, false].forEach((o) => {
4884 throws(() => data[`write${fn}`](23, o), { name: 'TypeError' });
4885 });
4886 
4887 [NaN, Infinity, -1, 1.01].forEach((o) => {
4888 throws(() => data[`write${fn}`](23, o), { name: 'RangeError' });
4889 });
4890 }
4891 );
4892 }
4893 
4894 {
4895 // Test 8 bit
4896 const data = Buffer.alloc(4);
4897 
4898 data.writeUInt8(23, 0);
4899 data.writeUInt8(23, 1);
4900 data.writeUInt8(23, 2);
4901 data.writeUInt8(23, 3);
4902 ok(data.equals(new Uint8Array([23, 23, 23, 23])));
4903 
4904 data.writeUInt8(23, 0);
4905 data.writeUInt8(23, 1);
4906 data.writeUInt8(23, 2);
4907 data.writeUInt8(23, 3);
4908 ok(data.equals(new Uint8Array([23, 23, 23, 23])));
4909 
4910 data.writeUInt8(255, 0);
4911 strictEqual(data[0], 255);
4912 
4913 data.writeUInt8(255, 0);
4914 strictEqual(data[0], 255);
4915 }
4916 
4917 // Test 16 bit
4918 {
4919 let value = 0x2343;
4920 const data = Buffer.alloc(4);
4921 
4922 data.writeUInt16BE(value, 0);
4923 ok(data.equals(new Uint8Array([0x23, 0x43, 0, 0])));
4924 
4925 data.writeUInt16BE(value, 1);
4926 ok(data.equals(new Uint8Array([0x23, 0x23, 0x43, 0])));
4927 
4928 data.writeUInt16BE(value, 2);
4929 ok(data.equals(new Uint8Array([0x23, 0x23, 0x23, 0x43])));
4930 
4931 data.writeUInt16LE(value, 0);
4932 ok(data.equals(new Uint8Array([0x43, 0x23, 0x23, 0x43])));
4933 
4934 data.writeUInt16LE(value, 1);
4935 ok(data.equals(new Uint8Array([0x43, 0x43, 0x23, 0x43])));
4936 
4937 data.writeUInt16LE(value, 2);
4938 ok(data.equals(new Uint8Array([0x43, 0x43, 0x43, 0x23])));
4939 
4940 value = 0xff80;
4941 data.writeUInt16LE(value, 0);
4942 ok(data.equals(new Uint8Array([0x80, 0xff, 0x43, 0x23])));
4943 
4944 data.writeUInt16BE(value, 0);
4945 ok(data.equals(new Uint8Array([0xff, 0x80, 0x43, 0x23])));
4946 
4947 value = 0xfffff;
4948 ['writeUInt16BE', 'writeUInt16LE'].forEach((fn) => {
4949 throws(() => data[fn](value, 0), {
4950 name: 'RangeError',
4951 });
4952 });
4953 }
4954 
4955 // Test 32 bit
4956 {
4957 const data = Buffer.alloc(6);
4958 const value = 0xe7f90a6d;
4959 
4960 data.writeUInt32BE(value, 0);
4961 ok(data.equals(new Uint8Array([0xe7, 0xf9, 0x0a, 0x6d, 0, 0])));
4962 
4963 data.writeUInt32BE(value, 1);
4964 ok(data.equals(new Uint8Array([0xe7, 0xe7, 0xf9, 0x0a, 0x6d, 0])));
4965 
4966 data.writeUInt32BE(value, 2);
4967 ok(data.equals(new Uint8Array([0xe7, 0xe7, 0xe7, 0xf9, 0x0a, 0x6d])));
4968 
4969 data.writeUInt32LE(value, 0);
4970 ok(data.equals(new Uint8Array([0x6d, 0x0a, 0xf9, 0xe7, 0x0a, 0x6d])));
4971 
4972 data.writeUInt32LE(value, 1);
4973 ok(data.equals(new Uint8Array([0x6d, 0x6d, 0x0a, 0xf9, 0xe7, 0x6d])));
4974 
4975 data.writeUInt32LE(value, 2);
4976 ok(data.equals(new Uint8Array([0x6d, 0x6d, 0x6d, 0x0a, 0xf9, 0xe7])));
4977 }
4978 
4979 // Test 48 bit
4980 {
4981 const value = 0x1234567890ab;
4982 const data = Buffer.allocUnsafe(6);
4983 data.writeUIntBE(value, 0, 6);
4984 ok(data.equals(new Uint8Array([0x12, 0x34, 0x56, 0x78, 0x90, 0xab])));
4985 
4986 data.writeUIntLE(value, 0, 6);
4987 ok(data.equals(new Uint8Array([0xab, 0x90, 0x78, 0x56, 0x34, 0x12])));
4988 }
4989 
4990 // Test UInt
4991 {
4992 const data = Buffer.alloc(8);
4993 let val = 0x100;
4994 
4995 // Check byteLength.
4996 ['writeUIntBE', 'writeUIntLE'].forEach((fn) => {
4997 ['', '0', null, {}, [], () => {}, true, false, undefined].forEach(
4998 (bl) => {
4999 throws(() => data[fn](23, 0, bl), { name: 'RangeError' });
5000 }
5001 );
5002 
5003 [Infinity, -1].forEach((byteLength) => {
5004 throws(() => data[fn](23, 0, byteLength), {
5005 name: 'RangeError',
5006 });
5007 });
5008 
5009 [NaN, 1.01].forEach((byteLength) => {
5010 throws(() => data[fn](42, 0, byteLength), {
5011 name: 'RangeError',
5012 });
5013 });
5014 });
5015 
5016 // Test 1 to 6 bytes.
5017 for (let i = 1; i <= 6; i++) {
5018 const _range = i < 5 ? `= ${val - 1}` : ` 2 ** ${i * 8}`;
5019 const _received =
5020 i > 4 ? String(val).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1_') : val;
5021 ['writeUIntBE', 'writeUIntLE'].forEach((fn) => {
5022 throws(
5023 () => {
5024 data[fn](val, 0, i);
5025 },
5026 {
5027 name: 'RangeError',
5028 }
5029 );
5030 
5031 ['', '0', null, {}, [], () => {}, true, false].forEach((o) => {
5032 throws(() => data[fn](23, o, i), {
5033 name: 'TypeError',
5034 });
5035 });
5036 
5037 [Infinity, -1, -4294967295].forEach((offset) => {
5038 throws(() => data[fn](val - 1, offset, i), {
5039 name: 'RangeError',
5040 });
5041 });
5042 
5043 [NaN, 1.01].forEach((offset) => {
5044 throws(() => data[fn](val - 1, offset, i), {
5045 name: 'RangeError',
5046 });
5047 });
5048 });
5049 
5050 val *= 0x100;
5051 }
5052 }
5053 
5054 for (const fn of [
5055 'UInt8',
5056 'UInt16LE',
5057 'UInt16BE',
5058 'UInt32LE',
5059 'UInt32BE',
5060 'UIntLE',
5061 'UIntBE',
5062 'BigUInt64LE',
5063 'BigUInt64BE',
5064 ]) {
5065 const p = Buffer.prototype;
5066 const lowerFn = fn.replace(/UInt/, 'Uint');
5067 strictEqual(p[`write${fn}`], p[`write${lowerFn}`]);
5068 strictEqual(p[`read${fn}`], p[`read${lowerFn}`]);
5069 }
5070 },
5071};
5072 
5073export const writeInt = {
5074 test(ctrl, env, ctx) {
5075 const errorOutOfBounds = {
5076 name: 'RangeError',
5077 };
5078 
5079 // Test 8 bit
5080 {
5081 const buffer = Buffer.alloc(2);
5082 
5083 buffer.writeInt8(0x23, 0);
5084 buffer.writeInt8(-5, 1);
5085 ok(buffer.equals(new Uint8Array([0x23, 0xfb])));
5086 
5087 /* Make sure we handle min/max correctly */
5088 buffer.writeInt8(0x7f, 0);
5089 buffer.writeInt8(-0x80, 1);
5090 ok(buffer.equals(new Uint8Array([0x7f, 0x80])));
5091 
5092 throws(() => {
5093 buffer.writeInt8(0x7f + 1, 0);
5094 }, errorOutOfBounds);
5095 throws(() => {
5096 buffer.writeInt8(-0x80 - 1, 0);
5097 }, errorOutOfBounds);
5098 
5099 // Verify that default offset works fine.
5100 buffer.writeInt8(23, undefined);
5101 buffer.writeInt8(23);
5102 
5103 ['', '0', null, {}, [], () => {}, true, false].forEach((off) => {
5104 throws(() => buffer.writeInt8(23, off), { name: 'TypeError' });
5105 });
5106 
5107 [NaN, Infinity, -1, 1.01].forEach((off) => {
5108 throws(() => buffer.writeInt8(23, off), { name: 'RangeError' });
5109 });
5110 }
5111 
5112 // Test 16 bit
5113 {
5114 const buffer = Buffer.alloc(4);
5115 
5116 buffer.writeInt16BE(0x0023, 0);
5117 buffer.writeInt16LE(0x0023, 2);
5118 ok(buffer.equals(new Uint8Array([0x00, 0x23, 0x23, 0x00])));
5119 
5120 buffer.writeInt16BE(-5, 0);
5121 buffer.writeInt16LE(-5, 2);
5122 ok(buffer.equals(new Uint8Array([0xff, 0xfb, 0xfb, 0xff])));
5123 
5124 buffer.writeInt16BE(-1679, 0);
5125 buffer.writeInt16LE(-1679, 2);
5126 ok(buffer.equals(new Uint8Array([0xf9, 0x71, 0x71, 0xf9])));
5127 
5128 /* Make sure we handle min/max correctly */
5129 buffer.writeInt16BE(0x7fff, 0);
5130 buffer.writeInt16BE(-0x8000, 2);
5131 ok(buffer.equals(new Uint8Array([0x7f, 0xff, 0x80, 0x00])));
5132 
5133 buffer.writeInt16LE(0x7fff, 0);
5134 buffer.writeInt16LE(-0x8000, 2);
5135 ok(buffer.equals(new Uint8Array([0xff, 0x7f, 0x00, 0x80])));
5136 
5137 ['writeInt16BE', 'writeInt16LE'].forEach((fn) => {
5138 // Verify that default offset works fine.
5139 buffer[fn](23, undefined);
5140 buffer[fn](23);
5141 
5142 throws(() => {
5143 buffer[fn](0x7fff + 1, 0);
5144 }, errorOutOfBounds);
5145 throws(() => {
5146 buffer[fn](-0x8000 - 1, 0);
5147 }, errorOutOfBounds);
5148 
5149 ['', '0', null, {}, [], () => {}, true, false].forEach((off) => {
5150 throws(() => buffer[fn](23, off), { code: 'ERR_INVALID_ARG_TYPE' });
5151 });
5152 
5153 [NaN, Infinity, -1, 1.01].forEach((off) => {
5154 throws(() => buffer[fn](23, off), { code: 'ERR_OUT_OF_RANGE' });
5155 });
5156 });
5157 }
5158 
5159 // Test 32 bit
5160 {
5161 const buffer = Buffer.alloc(8);
5162 
5163 buffer.writeInt32BE(0x23, 0);
5164 buffer.writeInt32LE(0x23, 4);
5165 ok(
5166 buffer.equals(
5167 new Uint8Array([0x00, 0x00, 0x00, 0x23, 0x23, 0x00, 0x00, 0x00])
5168 )
5169 );
5170 
5171 buffer.writeInt32BE(-5, 0);
5172 buffer.writeInt32LE(-5, 4);
5173 ok(
5174 buffer.equals(
5175 new Uint8Array([0xff, 0xff, 0xff, 0xfb, 0xfb, 0xff, 0xff, 0xff])
5176 )
5177 );
5178 
5179 buffer.writeInt32BE(-805306713, 0);
5180 buffer.writeInt32LE(-805306713, 4);
5181 ok(
5182 buffer.equals(
5183 new Uint8Array([0xcf, 0xff, 0xfe, 0xa7, 0xa7, 0xfe, 0xff, 0xcf])
5184 )
5185 );
5186 
5187 /* Make sure we handle min/max correctly */
5188 buffer.writeInt32BE(0x7fffffff, 0);
5189 buffer.writeInt32BE(-0x80000000, 4);
5190 ok(
5191 buffer.equals(
5192 new Uint8Array([0x7f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00])
5193 )
5194 );
5195 
5196 buffer.writeInt32LE(0x7fffffff, 0);
5197 buffer.writeInt32LE(-0x80000000, 4);
5198 ok(
5199 buffer.equals(
5200 new Uint8Array([0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x80])
5201 )
5202 );
5203 
5204 ['writeInt32BE', 'writeInt32LE'].forEach((fn) => {
5205 // Verify that default offset works fine.
5206 buffer[fn](23, undefined);
5207 buffer[fn](23);
5208 
5209 throws(() => {
5210 buffer[fn](0x7fffffff + 1, 0);
5211 }, errorOutOfBounds);
5212 throws(() => {
5213 buffer[fn](-0x80000000 - 1, 0);
5214 }, errorOutOfBounds);
5215 
5216 ['', '0', null, {}, [], () => {}, true, false].forEach((off) => {
5217 throws(() => buffer[fn](23, off), { code: 'ERR_INVALID_ARG_TYPE' });
5218 });
5219 
5220 [NaN, Infinity, -1, 1.01].forEach((off) => {
5221 throws(() => buffer[fn](23, off), { code: 'ERR_OUT_OF_RANGE' });
5222 });
5223 });
5224 }
5225 
5226 // Test 48 bit
5227 {
5228 const value = 0x1234567890ab;
5229 const buffer = Buffer.allocUnsafe(6);
5230 buffer.writeIntBE(value, 0, 6);
5231 ok(buffer.equals(new Uint8Array([0x12, 0x34, 0x56, 0x78, 0x90, 0xab])));
5232 
5233 buffer.writeIntLE(value, 0, 6);
5234 ok(buffer.equals(new Uint8Array([0xab, 0x90, 0x78, 0x56, 0x34, 0x12])));
5235 }
5236 
5237 // Test Int
5238 {
5239 const data = Buffer.alloc(8);
5240 
5241 // Check byteLength.
5242 ['writeIntBE', 'writeIntLE'].forEach((fn) => {
5243 ['', '0', null, {}, [], () => {}, true, false, undefined].forEach(
5244 (bl) => {
5245 throws(() => data[fn](23, 0, bl), { name: 'RangeError' });
5246 }
5247 );
5248 
5249 [Infinity, -1].forEach((byteLength) => {
5250 throws(() => data[fn](23, 0, byteLength), {
5251 name: 'RangeError',
5252 });
5253 });
5254 
5255 [NaN, 1.01].forEach((byteLength) => {
5256 throws(() => data[fn](42, 0, byteLength), {
5257 name: 'RangeError',
5258 });
5259 });
5260 });
5261 
5262 // Test 1 to 6 bytes.
5263 for (let i = 1; i <= 6; i++) {
5264 ['writeIntBE', 'writeIntLE'].forEach((fn) => {
5265 const min = -(2 ** (i * 8 - 1));
5266 const max = 2 ** (i * 8 - 1) - 1;
5267 let _range = `>= ${min} and <= ${max}`;
5268 if (i > 4) {
5269 _range = `>= -(2 ** ${i * 8 - 1}) and < 2 ** ${i * 8 - 1}`;
5270 }
5271 [min - 1, max + 1].forEach((val) => {
5272 const _received =
5273 i > 4
5274 ? String(val).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1_')
5275 : val;
5276 throws(
5277 () => {
5278 data[fn](val, 0, i);
5279 },
5280 {
5281 name: 'RangeError',
5282 }
5283 );
5284 });
5285 
5286 ['', '0', null, {}, [], () => {}, true, false, undefined].forEach(
5287 (o) => {
5288 throws(() => data[fn](min, o, i), {
5289 name: 'TypeError',
5290 });
5291 }
5292 );
5293 
5294 [Infinity, -1, -4294967295].forEach((offset) => {
5295 throws(() => data[fn](min, offset, i), {
5296 name: 'RangeError',
5297 });
5298 });
5299 
5300 [NaN, 1.01].forEach((offset) => {
5301 throws(() => data[fn](max, offset, i), {
5302 name: 'RangeError',
5303 });
5304 });
5305 });
5306 }
5307 }
5308 },
5309};
5310 
5311export const writeFloat = {
5312 test(ctrl, env, ctx) {
5313 const buffer = Buffer.allocUnsafe(8);
5314 
5315 buffer.writeFloatBE(1, 0);
5316 buffer.writeFloatLE(1, 4);
5317 ok(
5318 buffer.equals(
5319 new Uint8Array([0x3f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f])
5320 )
5321 );
5322 
5323 buffer.writeFloatBE(1 / 3, 0);
5324 buffer.writeFloatLE(1 / 3, 4);
5325 ok(
5326 buffer.equals(
5327 new Uint8Array([0x3e, 0xaa, 0xaa, 0xab, 0xab, 0xaa, 0xaa, 0x3e])
5328 )
5329 );
5330 
5331 buffer.writeFloatBE(3.4028234663852886e38, 0);
5332 buffer.writeFloatLE(3.4028234663852886e38, 4);
5333 ok(
5334 buffer.equals(
5335 new Uint8Array([0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f])
5336 )
5337 );
5338 
5339 buffer.writeFloatLE(1.1754943508222875e-38, 0);
5340 buffer.writeFloatBE(1.1754943508222875e-38, 4);
5341 ok(
5342 buffer.equals(
5343 new Uint8Array([0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00])
5344 )
5345 );
5346 
5347 buffer.writeFloatBE(0 * -1, 0);
5348 buffer.writeFloatLE(0 * -1, 4);
5349 ok(
5350 buffer.equals(
5351 new Uint8Array([0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80])
5352 )
5353 );
5354 
5355 buffer.writeFloatBE(Infinity, 0);
5356 buffer.writeFloatLE(Infinity, 4);
5357 ok(
5358 buffer.equals(
5359 new Uint8Array([0x7f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7f])
5360 )
5361 );
5362 
5363 strictEqual(buffer.readFloatBE(0), Infinity);
5364 strictEqual(buffer.readFloatLE(4), Infinity);
5365 
5366 buffer.writeFloatBE(-Infinity, 0);
5367 buffer.writeFloatLE(-Infinity, 4);
5368 ok(
5369 buffer.equals(
5370 new Uint8Array([0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff])
5371 )
5372 );
5373 
5374 strictEqual(buffer.readFloatBE(0), -Infinity);
5375 strictEqual(buffer.readFloatLE(4), -Infinity);
5376 
5377 buffer.writeFloatBE(NaN, 0);
5378 buffer.writeFloatLE(NaN, 4);
5379 
5380 // JS only knows a single NaN but there exist two platform specific
5381 // implementations. Therefore, allow both quiet and signalling NaNs.
5382 if (buffer[1] === 0xbf) {
5383 ok(
5384 buffer.equals(
5385 new Uint8Array([0x7f, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x7f])
5386 )
5387 );
5388 } else {
5389 ok(
5390 buffer.equals(
5391 new Uint8Array([0x7f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x7f])
5392 )
5393 );
5394 }
5395 
5396 ok(Number.isNaN(buffer.readFloatBE(0)));
5397 ok(Number.isNaN(buffer.readFloatLE(4)));
5398 
5399 // OOB in writeFloat{LE,BE} should throw.
5400 {
5401 const small = Buffer.allocUnsafe(1);
5402 
5403 ['writeFloatLE', 'writeFloatBE'].forEach((fn) => {
5404 // Verify that default offset works fine.
5405 buffer[fn](23, undefined);
5406 buffer[fn](23);
5407 
5408 throws(() => small[fn](11.11, 0), {
5409 name: 'RangeError',
5410 });
5411 
5412 ['', '0', null, {}, [], () => {}, true, false].forEach((off) => {
5413 throws(() => small[fn](23, off), { name: 'TypeError' });
5414 });
5415 
5416 [Infinity, -1, 5].forEach((offset) => {
5417 throws(() => buffer[fn](23, offset), {
5418 name: 'RangeError',
5419 });
5420 });
5421 
5422 [NaN, 1.01].forEach((offset) => {
5423 throws(() => buffer[fn](42, offset), {
5424 name: 'RangeError',
5425 });
5426 });
5427 });
5428 }
5429 },
5430};
5431 
5432export const writeDouble = {
5433 test(ctrl, env, ctx) {
5434 const buffer = Buffer.allocUnsafe(16);
5435 
5436 buffer.writeDoubleBE(2.225073858507201e-308, 0);
5437 buffer.writeDoubleLE(2.225073858507201e-308, 8);
5438 ok(
5439 buffer.equals(
5440 new Uint8Array([
5441 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
5442 0xff, 0xff, 0xff, 0x0f, 0x00,
5443 ])
5444 )
5445 );
5446 
5447 buffer.writeDoubleBE(1.0000000000000004, 0);
5448 buffer.writeDoubleLE(1.0000000000000004, 8);
5449 ok(
5450 buffer.equals(
5451 new Uint8Array([
5452 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00,
5453 0x00, 0x00, 0x00, 0xf0, 0x3f,
5454 ])
5455 )
5456 );
5457 
5458 buffer.writeDoubleBE(-2, 0);
5459 buffer.writeDoubleLE(-2, 8);
5460 ok(
5461 buffer.equals(
5462 new Uint8Array([
5463 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5464 0x00, 0x00, 0x00, 0x00, 0xc0,
5465 ])
5466 )
5467 );
5468 
5469 buffer.writeDoubleBE(1.7976931348623157e308, 0);
5470 buffer.writeDoubleLE(1.7976931348623157e308, 8);
5471 ok(
5472 buffer.equals(
5473 new Uint8Array([
5474 0x7f, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
5475 0xff, 0xff, 0xff, 0xef, 0x7f,
5476 ])
5477 )
5478 );
5479 
5480 buffer.writeDoubleBE(0 * -1, 0);
5481 buffer.writeDoubleLE(0 * -1, 8);
5482 ok(
5483 buffer.equals(
5484 new Uint8Array([
5485 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5486 0x00, 0x00, 0x00, 0x00, 0x80,
5487 ])
5488 )
5489 );
5490 
5491 buffer.writeDoubleBE(Infinity, 0);
5492 buffer.writeDoubleLE(Infinity, 8);
5493 
5494 ok(
5495 buffer.equals(
5496 new Uint8Array([
5497 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5498 0x00, 0x00, 0x00, 0xf0, 0x7f,
5499 ])
5500 )
5501 );
5502 
5503 strictEqual(buffer.readDoubleBE(0), Infinity);
5504 strictEqual(buffer.readDoubleLE(8), Infinity);
5505 
5506 buffer.writeDoubleBE(-Infinity, 0);
5507 buffer.writeDoubleLE(-Infinity, 8);
5508 
5509 ok(
5510 buffer.equals(
5511 new Uint8Array([
5512 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5513 0x00, 0x00, 0x00, 0xf0, 0xff,
5514 ])
5515 )
5516 );
5517 
5518 strictEqual(buffer.readDoubleBE(0), -Infinity);
5519 strictEqual(buffer.readDoubleLE(8), -Infinity);
5520 
5521 buffer.writeDoubleBE(NaN, 0);
5522 buffer.writeDoubleLE(NaN, 8);
5523 
5524 // JS only knows a single NaN but there exist two platform specific
5525 // implementations. Therefore, allow both quiet and signalling NaNs.
5526 if (buffer[1] === 0xf7) {
5527 ok(
5528 buffer.equals(
5529 new Uint8Array([
5530 0x7f, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
5531 0xff, 0xff, 0xff, 0xf7, 0x7f,
5532 ])
5533 )
5534 );
5535 } else {
5536 ok(
5537 buffer.equals(
5538 new Uint8Array([
5539 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5540 0x00, 0x00, 0x00, 0xf8, 0x7f,
5541 ])
5542 )
5543 );
5544 }
5545 
5546 ok(Number.isNaN(buffer.readDoubleBE(0)));
5547 ok(Number.isNaN(buffer.readDoubleLE(8)));
5548 
5549 // OOB in writeDouble{LE,BE} should throw.
5550 {
5551 const small = Buffer.allocUnsafe(1);
5552 
5553 ['writeDoubleLE', 'writeDoubleBE'].forEach((fn) => {
5554 // Verify that default offset works fine.
5555 buffer[fn](23, undefined);
5556 buffer[fn](23);
5557 
5558 throws(() => small[fn](11.11, 0), {
5559 code: 'ERR_BUFFER_OUT_OF_BOUNDS',
5560 name: 'RangeError',
5561 message: 'Attempt to access memory outside buffer bounds',
5562 });
5563 
5564 ['', '0', null, {}, [], () => {}, true, false].forEach((off) => {
5565 throws(() => small[fn](23, off), { name: 'TypeError' });
5566 });
5567 
5568 [Infinity, -1, 9].forEach((offset) => {
5569 throws(() => buffer[fn](23, offset), {
5570 name: 'RangeError',
5571 });
5572 });
5573 
5574 [NaN, 1.01].forEach((offset) => {
5575 throws(() => buffer[fn](42, offset), {
5576 name: 'RangeError',
5577 });
5578 });
5579 });
5580 }
5581 },
5582};
5583 
5584export const write = {
5585 test(ctrl, env, ctx) {
5586 [-1, 10].forEach((offset) => {
5587 throws(() => Buffer.alloc(9).write('foo', offset), {
5588 name: 'RangeError',
5589 });
5590 });
5591 
5592 const resultMap = new Map([
5593 ['utf8', Buffer.from([102, 111, 111, 0, 0, 0, 0, 0, 0])],
5594 ['ucs2', Buffer.from([102, 0, 111, 0, 111, 0, 0, 0, 0])],
5595 ['ascii', Buffer.from([102, 111, 111, 0, 0, 0, 0, 0, 0])],
5596 ['latin1', Buffer.from([102, 111, 111, 0, 0, 0, 0, 0, 0])],
5597 ['binary', Buffer.from([102, 111, 111, 0, 0, 0, 0, 0, 0])],
5598 ['utf16le', Buffer.from([102, 0, 111, 0, 111, 0, 0, 0, 0])],
5599 ['base64', Buffer.from([102, 111, 111, 0, 0, 0, 0, 0, 0])],
5600 ['base64url', Buffer.from([102, 111, 111, 0, 0, 0, 0, 0, 0])],
5601 ['hex', Buffer.from([102, 111, 111, 0, 0, 0, 0, 0, 0])],
5602 ]);
5603 
5604 // utf8, ucs2, ascii, latin1, utf16le
5605 const encodings = [
5606 'utf8',
5607 'utf-8',
5608 'ascii',
5609 'latin1',
5610 'binary',
5611 'ucs2',
5612 'ucs-2',
5613 'utf16le',
5614 'utf-16le',
5615 ];
5616 
5617 encodings
5618 .reduce((es, e) => es.concat(e, e.toUpperCase()), [])
5619 .forEach((encoding) => {
5620 const buf = Buffer.alloc(9);
5621 const len = Buffer.byteLength('foo', encoding);
5622 strictEqual(buf.write('foo', 0, len, encoding), len);
5623 
5624 if (encoding.includes('-')) encoding = encoding.replace('-', '');
5625 
5626 deepStrictEqual(buf, resultMap.get(encoding.toLowerCase()));
5627 });
5628 
5629 // base64
5630 ['base64', 'BASE64', 'base64url', 'BASE64URL'].forEach((encoding) => {
5631 const buf = Buffer.alloc(9);
5632 const len = Buffer.byteLength('Zm9v', encoding);
5633 
5634 strictEqual(buf.write('Zm9v', 0, len, encoding), len);
5635 deepStrictEqual(buf, resultMap.get(encoding.toLowerCase()));
5636 });
5637 
5638 // hex
5639 ['hex', 'HEX'].forEach((encoding) => {
5640 const buf = Buffer.alloc(9);
5641 const len = Buffer.byteLength('666f6f', encoding);
5642 
5643 strictEqual(buf.write('666f6f', 0, len, encoding), len);
5644 deepStrictEqual(buf, resultMap.get(encoding.toLowerCase()));
5645 });
5646 
5647 // Invalid encodings
5648 for (let i = 1; i < 10; i++) {
5649 const encoding = String(i).repeat(i);
5650 const error = {
5651 name: 'TypeError',
5652 };
5653 
5654 ok(!Buffer.isEncoding(encoding));
5655 throws(() => Buffer.alloc(9).write('foo', encoding), error);
5656 }
5657 
5658 // UCS-2 overflow CVE-2018-12115
5659 for (let i = 1; i < 4; i++) {
5660 // Allocate two Buffers sequentially off the pool. Run more than once in case
5661 // we hit the end of the pool and don't get sequential allocations
5662 const x = Buffer.allocUnsafe(4).fill(0);
5663 const y = Buffer.allocUnsafe(4).fill(1);
5664 // Should not write anything, pos 3 doesn't have enough room for a 16-bit char
5665 strictEqual(x.write('ыыыыыы', 3, 'ucs2'), 0);
5666 // CVE-2018-12115 experienced via buffer overrun to next block in the pool
5667 strictEqual(Buffer.compare(y, Buffer.alloc(4, 1)), 0);
5668 }
5669 
5670 // Should not write any data when there is no space for 16-bit chars
5671 const z = Buffer.alloc(4, 0);
5672 strictEqual(z.write('\u0001', 3, 'ucs2'), 0);
5673 strictEqual(Buffer.compare(z, Buffer.alloc(4, 0)), 0);
5674 // Make sure longer strings are written up to the buffer end.
5675 strictEqual(z.write('abcd', 2), 2);
5676 deepStrictEqual([...z], [0, 0, 0x61, 0x62]);
5677 
5678 // Large overrun could corrupt the process
5679 strictEqual(Buffer.alloc(4).write('ыыыыыы'.repeat(100), 3, 'utf16le'), 0);
5680 
5681 {
5682 // .write() does not affect the byte after the written-to slice of the Buffer.
5683 // Refs: https://github.com/nodejs/node/issues/26422
5684 const buf = Buffer.alloc(8);
5685 strictEqual(buf.write('ыы', 1, 'utf16le'), 4);
5686 deepStrictEqual([...buf], [0, 0x4b, 0x04, 0x4b, 0x04, 0, 0, 0]);
5687 }
5688 },
5689};
5690 
5691export const toString = {
5692 test(ctrl, env, ctx) {
5693 // utf8, ucs2, ascii, latin1, utf16le
5694 const encodings = [
5695 'utf8',
5696 'utf-8',
5697 'ucs2',
5698 'ucs-2',
5699 'ascii',
5700 'latin1',
5701 'binary',
5702 'utf16le',
5703 'utf-16le',
5704 ];
5705 
5706 encodings
5707 .reduce((es, e) => es.concat(e, e.toUpperCase()), [])
5708 .forEach((encoding) => {
5709 strictEqual(Buffer.from('foo', encoding).toString(encoding), 'foo');
5710 });
5711 
5712 // base64
5713 ['base64', 'BASE64'].forEach((encoding) => {
5714 strictEqual(Buffer.from('Zm9v', encoding).toString(encoding), 'Zm9v');
5715 });
5716 
5717 // hex
5718 ['hex', 'HEX'].forEach((encoding) => {
5719 strictEqual(Buffer.from('666f6f', encoding).toString(encoding), '666f6f');
5720 });
5721 
5722 // default utf-8 if undefined
5723 strictEqual(Buffer.from('utf-8').toString(), 'utf-8');
5724 
5725 const invalidEncodings = Array.from({ length: 10 }, (_, i) =>
5726 String(i + 1).repeat(i + 1)
5727 );
5728 // Invalid encodings
5729 for (const encoding of [...invalidEncodings, null]) {
5730 const error = {
5731 code: 'ERR_UNKNOWN_ENCODING',
5732 name: 'TypeError',
5733 message: `Unknown encoding: ${encoding}`,
5734 };
5735 ok(!Buffer.isEncoding(encoding));
5736 throws(() => Buffer.from('foo').toString(encoding), error);
5737 }
5738 },
5739};
5740 
5741export const toStringRangeError = {
5742 test(ctrl, env, ctx) {
5743 const len = 1422561062959;
5744 const message = {
5745 code: 'ERR_OUT_OF_RANGE',
5746 name: 'RangeError',
5747 };
5748 throws(() => Buffer(len).toString('utf8'), message);
5749 throws(() => SlowBuffer(len).toString('utf8'), message);
5750 throws(() => Buffer.alloc(len).toString('utf8'), message);
5751 throws(() => Buffer.allocUnsafe(len).toString('utf8'), message);
5752 throws(() => Buffer.allocUnsafeSlow(len).toString('utf8'), message);
5753 },
5754};
5755 
5756export const toStringRange = {
5757 test(ctrl, env, ctx) {
5758 const rangeBuffer = Buffer.from('abc');
5759 // If start >= buffer's length, empty string will be returned
5760 strictEqual(rangeBuffer.toString('ascii', 3), '');
5761 strictEqual(rangeBuffer.toString('ascii', +Infinity), '');
5762 strictEqual(rangeBuffer.toString('ascii', 3.14, 3), '');
5763 strictEqual(rangeBuffer.toString('ascii', 'Infinity', 3), '');
5764 
5765 // If end <= 0, empty string will be returned
5766 strictEqual(rangeBuffer.toString('ascii', 1, 0), '');
5767 strictEqual(rangeBuffer.toString('ascii', 1, -1.2), '');
5768 strictEqual(rangeBuffer.toString('ascii', 1, -100), '');
5769 strictEqual(rangeBuffer.toString('ascii', 1, -Infinity), '');
5770 
5771 // If start < 0, start will be taken as zero
5772 strictEqual(rangeBuffer.toString('ascii', -1, 3), 'abc');
5773 strictEqual(rangeBuffer.toString('ascii', -1.99, 3), 'abc');
5774 strictEqual(rangeBuffer.toString('ascii', -Infinity, 3), 'abc');
5775 strictEqual(rangeBuffer.toString('ascii', '-1', 3), 'abc');
5776 strictEqual(rangeBuffer.toString('ascii', '-1.99', 3), 'abc');
5777 strictEqual(rangeBuffer.toString('ascii', '-Infinity', 3), 'abc');
5778 
5779 // If start is an invalid integer, start will be taken as zero
5780 strictEqual(rangeBuffer.toString('ascii', 'node.js', 3), 'abc');
5781 strictEqual(rangeBuffer.toString('ascii', {}, 3), 'abc');
5782 strictEqual(rangeBuffer.toString('ascii', [], 3), 'abc');
5783 strictEqual(rangeBuffer.toString('ascii', NaN, 3), 'abc');
5784 strictEqual(rangeBuffer.toString('ascii', null, 3), 'abc');
5785 strictEqual(rangeBuffer.toString('ascii', undefined, 3), 'abc');
5786 strictEqual(rangeBuffer.toString('ascii', false, 3), 'abc');
5787 strictEqual(rangeBuffer.toString('ascii', '', 3), 'abc');
5788 
5789 // But, if start is an integer when coerced, then it will be coerced and used.
5790 strictEqual(rangeBuffer.toString('ascii', '-1', 3), 'abc');
5791 strictEqual(rangeBuffer.toString('ascii', '1', 3), 'bc');
5792 strictEqual(rangeBuffer.toString('ascii', '-Infinity', 3), 'abc');
5793 strictEqual(rangeBuffer.toString('ascii', '3', 3), '');
5794 strictEqual(rangeBuffer.toString('ascii', Number(3), 3), '');
5795 strictEqual(rangeBuffer.toString('ascii', '3.14', 3), '');
5796 strictEqual(rangeBuffer.toString('ascii', '1.99', 3), 'bc');
5797 strictEqual(rangeBuffer.toString('ascii', '-1.99', 3), 'abc');
5798 strictEqual(rangeBuffer.toString('ascii', 1.99, 3), 'bc');
5799 strictEqual(rangeBuffer.toString('ascii', true, 3), 'bc');
5800 
5801 // If end > buffer's length, end will be taken as buffer's length
5802 strictEqual(rangeBuffer.toString('ascii', 0, 5), 'abc');
5803 strictEqual(rangeBuffer.toString('ascii', 0, 6.99), 'abc');
5804 strictEqual(rangeBuffer.toString('ascii', 0, Infinity), 'abc');
5805 strictEqual(rangeBuffer.toString('ascii', 0, '5'), 'abc');
5806 strictEqual(rangeBuffer.toString('ascii', 0, '6.99'), 'abc');
5807 strictEqual(rangeBuffer.toString('ascii', 0, 'Infinity'), 'abc');
5808 
5809 // If end is an invalid integer, end will be taken as buffer's length
5810 strictEqual(rangeBuffer.toString('ascii', 0, 'node.js'), '');
5811 strictEqual(rangeBuffer.toString('ascii', 0, {}), '');
5812 strictEqual(rangeBuffer.toString('ascii', 0, NaN), '');
5813 strictEqual(rangeBuffer.toString('ascii', 0, undefined), 'abc');
5814 strictEqual(rangeBuffer.toString('ascii', 0), 'abc');
5815 strictEqual(rangeBuffer.toString('ascii', 0, null), '');
5816 strictEqual(rangeBuffer.toString('ascii', 0, []), '');
5817 strictEqual(rangeBuffer.toString('ascii', 0, false), '');
5818 strictEqual(rangeBuffer.toString('ascii', 0, ''), '');
5819 
5820 // But, if end is an integer when coerced, then it will be coerced and used.
5821 strictEqual(rangeBuffer.toString('ascii', 0, '-1'), '');
5822 strictEqual(rangeBuffer.toString('ascii', 0, '1'), 'a');
5823 strictEqual(rangeBuffer.toString('ascii', 0, '-Infinity'), '');
5824 strictEqual(rangeBuffer.toString('ascii', 0, '3'), 'abc');
5825 strictEqual(rangeBuffer.toString('ascii', 0, Number(3)), 'abc');
5826 strictEqual(rangeBuffer.toString('ascii', 0, '3.14'), 'abc');
5827 strictEqual(rangeBuffer.toString('ascii', 0, '1.99'), 'a');
5828 strictEqual(rangeBuffer.toString('ascii', 0, '-1.99'), '');
5829 strictEqual(rangeBuffer.toString('ascii', 0, 1.99), 'a');
5830 strictEqual(rangeBuffer.toString('ascii', 0, true), 'a');
5831 
5832 // Try toString() with an object as an encoding
5833 strictEqual(
5834 rangeBuffer.toString({
5835 toString: function () {
5836 return 'ascii';
5837 },
5838 }),
5839 'abc'
5840 );
5841 
5842 // Try toString() with 0 and null as the encoding
5843 throws(
5844 () => {
5845 rangeBuffer.toString(0, 1, 2);
5846 },
5847 {
5848 name: 'TypeError',
5849 },
5850 'toString() with 0 and null as the encoding should have thrown'
5851 );
5852 
5853 throws(
5854 () => {
5855 rangeBuffer.toString(null, 1, 2);
5856 },
5857 {
5858 name: 'TypeError',
5859 },
5860 'toString() with null encoding should have thrown'
5861 );
5862 },
5863};
5864 
5865export const inspect = {
5866 // test-buffer-inspect.js
5867 async test(ctrl, env, ctx) {
5868 let b = Buffer.allocUnsafe(60);
5869 b.fill('0123456789'.repeat(6));
5870 
5871 let s = buffer.SlowBuffer(60);
5872 s.fill('0123456789'.repeat(6));
5873 
5874 let expected =
5875 '<Buffer 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 ... 10 more bytes>';
5876 
5877 strictEqual(util.inspect(b), expected);
5878 strictEqual(util.inspect(s), expected);
5879 
5880 b = Buffer.allocUnsafe(2);
5881 b.fill('12');
5882 
5883 s = buffer.SlowBuffer(2);
5884 s.fill('12');
5885 
5886 expected = '<Buffer 31 32>';
5887 
5888 strictEqual(util.inspect(b), expected);
5889 strictEqual(util.inspect(s), expected);
5890 
5891 b.inspect = undefined;
5892 b.prop = new Uint8Array(0);
5893 strictEqual(
5894 util.inspect(b),
5895 '<Buffer 31 32, inspect: undefined, prop: Uint8Array(0) []>'
5896 );
5897 
5898 b = Buffer.alloc(0);
5899 b.prop = 123;
5900 
5901 strictEqual(util.inspect(b), '<Buffer prop: 123>');
5902 },
5903};
5904 
5905export const isAsciiTest = {
5906 test(ctrl, env, ctx) {
5907 const encoder = new TextEncoder();
5908 strictEqual(isAscii(encoder.encode('hello')), true);
5909 strictEqual(isAscii(encoder.encode('ğ')), false);
5910 strictEqual(isAscii(Buffer.from([])), true);
5911 
5912 [
5913 undefined,
5914 '',
5915 'hello',
5916 false,
5917 true,
5918 0,
5919 1,
5920 0n,
5921 1n,
5922 Symbol(),
5923 () => {},
5924 {},
5925 [],
5926 null,
5927 ].forEach((input) => {
5928 throws(() => isAscii(input));
5929 });
5930 },
5931};
5932 
5933export const isUtf8Test = {
5934 test(ctrl, env, ctx) {
5935 const encoder = new TextEncoder();
5936 
5937 strictEqual(isUtf8(encoder.encode('hello')), true);
5938 strictEqual(isUtf8(encoder.encode('ğ')), true);
5939 strictEqual(isUtf8(Buffer.from([])), true);
5940 
5941 // Taken from test/fixtures/wpt/encoding/textdecoder-fatal.any.js
5942 [
5943 [0xff], // 'invalid code'
5944 [0xc0], // 'ends early'
5945 [0xe0], // 'ends early 2'
5946 [0xc0, 0x00], // 'invalid trail'
5947 [0xc0, 0xc0], // 'invalid trail 2'
5948 [0xe0, 0x00], // 'invalid trail 3'
5949 [0xe0, 0xc0], // 'invalid trail 4'
5950 [0xe0, 0x80, 0x00], // 'invalid trail 5'
5951 [0xe0, 0x80, 0xc0], // 'invalid trail 6'
5952 [0xfc, 0x80, 0x80, 0x80, 0x80, 0x80], // '> 0x10FFFF'
5953 [0xfe, 0x80, 0x80, 0x80, 0x80, 0x80], // 'obsolete lead byte'
5954 
5955 // Overlong encodings
5956 [0xc0, 0x80], // 'overlong U+0000 - 2 bytes'
5957 [0xe0, 0x80, 0x80], // 'overlong U+0000 - 3 bytes'
5958 [0xf0, 0x80, 0x80, 0x80], // 'overlong U+0000 - 4 bytes'
5959 [0xf8, 0x80, 0x80, 0x80, 0x80], // 'overlong U+0000 - 5 bytes'
5960 [0xfc, 0x80, 0x80, 0x80, 0x80, 0x80], // 'overlong U+0000 - 6 bytes'
5961 
5962 [0xc1, 0xbf], // 'overlong U+007F - 2 bytes'
5963 [0xe0, 0x81, 0xbf], // 'overlong U+007F - 3 bytes'
5964 [0xf0, 0x80, 0x81, 0xbf], // 'overlong U+007F - 4 bytes'
5965 [0xf8, 0x80, 0x80, 0x81, 0xbf], // 'overlong U+007F - 5 bytes'
5966 [0xfc, 0x80, 0x80, 0x80, 0x81, 0xbf], // 'overlong U+007F - 6 bytes'
5967 
5968 [0xe0, 0x9f, 0xbf], // 'overlong U+07FF - 3 bytes'
5969 [0xf0, 0x80, 0x9f, 0xbf], // 'overlong U+07FF - 4 bytes'
5970 [0xf8, 0x80, 0x80, 0x9f, 0xbf], // 'overlong U+07FF - 5 bytes'
5971 [0xfc, 0x80, 0x80, 0x80, 0x9f, 0xbf], // 'overlong U+07FF - 6 bytes'
5972 
5973 [0xf0, 0x8f, 0xbf, 0xbf], // 'overlong U+FFFF - 4 bytes'
5974 [0xf8, 0x80, 0x8f, 0xbf, 0xbf], // 'overlong U+FFFF - 5 bytes'
5975 [0xfc, 0x80, 0x80, 0x8f, 0xbf, 0xbf], // 'overlong U+FFFF - 6 bytes'
5976 
5977 [0xf8, 0x84, 0x8f, 0xbf, 0xbf], // 'overlong U+10FFFF - 5 bytes'
5978 [0xfc, 0x80, 0x84, 0x8f, 0xbf, 0xbf], // 'overlong U+10FFFF - 6 bytes'
5979 
5980 // UTF-16 surrogates encoded as code points in UTF-8
5981 [0xed, 0xa0, 0x80], // 'lead surrogate'
5982 [0xed, 0xb0, 0x80], // 'trail surrogate'
5983 [0xed, 0xa0, 0x80, 0xed, 0xb0, 0x80], // 'surrogate pair'
5984 ].forEach((input) => {
5985 strictEqual(isUtf8(Buffer.from(input)), false);
5986 });
5987 
5988 [null, undefined, 'hello', true, false].forEach((input) => {
5989 throws(() => isUtf8(input));
5990 });
5991 },
5992};
5993 
5994// Adapted from test/parallel/test-icu-transcode.js
5995export const transcodeTest = {
5996 test(ctrl, env, ctx) {
5997 const orig = Buffer.from('těst ☕', 'utf8');
5998 const tests = {
5999 latin1: [0x74, 0x3f, 0x73, 0x74, 0x20, 0x3f],
6000 ascii: [0x74, 0x3f, 0x73, 0x74, 0x20, 0x3f],
6001 ucs2: [
6002 0x74, 0x00, 0x1b, 0x01, 0x73, 0x00, 0x74, 0x00, 0x20, 0x00, 0x15, 0x26,
6003 ],
6004 };
6005 
6006 for (const test in tests) {
6007 const dest = transcode(orig, 'utf8', test);
6008 strictEqual(
6009 dest.length,
6010 tests[test].length,
6011 `utf8->${test} length (${dest.length}, ${tests[test].length})`
6012 );
6013 for (let n = 0; n < tests[test].length; n++) {
6014 strictEqual(dest[n], tests[test][n], `utf8->${test} char ${n}`);
6015 }
6016 }
6017 
6018 {
6019 const dest = transcode(Buffer.from(tests.ucs2), 'ucs2', 'utf8');
6020 strictEqual(dest.toString(), orig.toString());
6021 }
6022 
6023 // Test utf16le to ascii/latin1 output length
6024 {
6025 const input = Buffer.from('AAA', 'utf16le');
6026 strictEqual(input.length, 6);
6027 const asciiOutput = transcode(input, 'utf16le', 'ascii');
6028 strictEqual(asciiOutput.length, 3);
6029 deepStrictEqual(asciiOutput, Buffer.from('AAA', 'ascii'));
6030 const latin1Output = transcode(input, 'utf16le', 'latin1');
6031 strictEqual(latin1Output.length, 3);
6032 deepStrictEqual(latin1Output, Buffer.from('AAA', 'latin1'));
6033 }
6034 
6035 {
6036 const utf8 = Buffer.from('€'.repeat(4000), 'utf8');
6037 const ucs2 = Buffer.from('€'.repeat(4000), 'ucs2');
6038 const utf8_to_ucs2 = transcode(utf8, 'utf8', 'ucs2');
6039 const ucs2_to_utf8 = transcode(ucs2, 'ucs2', 'utf8');
6040 deepStrictEqual(utf8, ucs2_to_utf8);
6041 deepStrictEqual(ucs2, utf8_to_ucs2);
6042 strictEqual(ucs2_to_utf8.toString('utf8'), utf8_to_ucs2.toString('ucs2'));
6043 }
6044 
6045 {
6046 deepStrictEqual(
6047 transcode(Buffer.from('hi', 'ascii'), 'ascii', 'utf16le'),
6048 Buffer.from('hi', 'utf16le')
6049 );
6050 deepStrictEqual(
6051 transcode(Buffer.from('hi', 'latin1'), 'latin1', 'utf16le'),
6052 Buffer.from('hi', 'utf16le')
6053 );
6054 deepStrictEqual(
6055 transcode(Buffer.from('hä', 'latin1'), 'latin1', 'utf16le'),
6056 Buffer.from('hä', 'utf16le')
6057 );
6058 }
6059 
6060 {
6061 const dest = transcode(new Uint8Array(), 'utf8', 'latin1');
6062 strictEqual(dest.length, 0);
6063 }
6064 
6065 // Test that Uint8Array arguments are okay.
6066 {
6067 const uint8array = new Uint8Array(Buffer.from('hä', 'latin1'));
6068 deepStrictEqual(
6069 transcode(uint8array, 'latin1', 'utf16le'),
6070 Buffer.from('hä', 'utf16le')
6071 );
6072 }
6073 
6074 // Invalid arguments should fail
6075 throws(() => transcode(null, 'utf8', 'ascii'));
6076 throws(() => transcode(Buffer.from('a'), 'b', 'utf8'));
6077 throws(() => transcode(Buffer.from('a'), 'uf8', 'b'));
6078 
6079 // Throws error for buffer bigger than 128mb.
6080 {
6081 const ISOLATE_MAX_SIZE = 134217728;
6082 const val = Buffer.from('a'.repeat(ISOLATE_MAX_SIZE));
6083 
6084 throws(() => transcode(val, 'utf16le', 'utf8'));
6085 throws(() => transcode(val, 'latin1', 'utf16le'));
6086 }
6087 
6088 // Make sure same fromEncoding and toEncoding results in copy.
6089 {
6090 const original = Buffer.from('a');
6091 const copied_value = transcode(original, 'utf8', 'utf8');
6092 // Let's detach the copied_value
6093 const _ = copied_value.buffer.transfer();
6094 ok(copied_value.buffer.detached);
6095 ok(!original.buffer.detached);
6096 }
6097 
6098 // Same encoding types should return in a value that replaces
6099 // invalid characters with replacement characters.
6100 deepStrictEqual(
6101 transcode(Buffer.from([0x80]), 'utf8', 'utf8'),
6102 Buffer.from([0xef, 0xbf, 0xbd])
6103 );
6104 },
6105};
6106 
6107// TranscodeFromUTF16 should not over-allocate the output buffer.
6108// Regression test for a bug where `limit * sizeof(char16_t)` doubled the
6109// allocation and `destPtr.size()` passed char16_t element count instead of
6110// byte count to ucnv_fromUChars.
6111export const transcodeFromUTF16BufferSizeTest = {
6112 test() {
6113 const utf16 = Buffer.from('Hello', 'utf16le');
6114 const latin1 = transcode(utf16, 'utf16le', 'latin1');
6115 strictEqual(latin1.length, 5);
6116 strictEqual(latin1.buffer.byteLength, latin1.length);
6117 },
6118};
6119 
6120// Invalid UTF-8 input to transcode('utf8', 'utf16le') should produce
6121// "Unable to transcode buffer", not an internal assertion mismatch.
6122// Regression test for a bug where JSG_REQUIRE(actual == expected) threw
6123// before the `if (actual == 0) return kj::none` path could be reached.
6124export const transcodeUTF8ToUTF16InvalidInputTest = {
6125 test() {
6126 throws(
6127 () =>
6128 transcode(
6129 Buffer.from([0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x80]),
6130 'utf8',
6131 'utf16le'
6132 ),
6133 { message: /Unable to transcode buffer/ }
6134 );
6135 },
6136};
6137 
6138// TranscodeFromUTF16 should reject odd-byte UTF-16LE input, matching
6139// the guard that TranscodeUTF8FromUTF16 already has.
6140// Regression test for a bug where `source.size() / sizeof(char16_t)`
6141// silently dropped the trailing byte.
6142export const transcodeFromUTF16OddByteInputTest = {
6143 test() {
6144 const oddInput = Buffer.from([0x41, 0x00, 0x42]);
6145 throws(() => transcode(oddInput, 'utf16le', 'utf8'));
6146 throws(() => transcode(oddInput, 'utf16le', 'latin1'));
6147 throws(() => transcode(oddInput, 'utf16le', 'ascii'));
6148 },
6149};
6150 
6151// Tests are taken from Node.js
6152// https://github.com/nodejs/node/blob/a4f609fa/test/parallel/test-file.js
6153export const fileTest = {
6154 test() {
6155 throws(() => new File(), TypeError);
6156 throws(() => new File([]), TypeError);
6157 throws(() => File.prototype.name, TypeError);
6158 throws(() => File.prototype.lastModified, TypeError);
6159 
6160 {
6161 const keys = Object.keys(File.prototype).sort();
6162 deepStrictEqual(keys, ['lastModified', 'name']);
6163 }
6164 
6165 {
6166 const file = new File([], 'dummy.txt.exe');
6167 strictEqual(file.name, 'dummy.txt.exe');
6168 strictEqual(file.size, 0);
6169 strictEqual(typeof file.lastModified, 'number');
6170 ok(file.lastModified <= Date.now());
6171 }
6172 
6173 {
6174 const toPrimitive = {
6175 [Symbol.toPrimitive]() {
6176 return 'NaN';
6177 },
6178 };
6179 
6180 const invalidLastModified = [null, 'string', false, toPrimitive];
6181 
6182 for (const lastModified of invalidLastModified) {
6183 const file = new File([], '', { lastModified });
6184 strictEqual(file.lastModified, 0);
6185 }
6186 }
6187 
6188 {
6189 const file = new File([], '', { lastModified: undefined });
6190 notStrictEqual(file.lastModified, 0);
6191 }
6192 
6193 {
6194 const toPrimitive = {
6195 [Symbol.toPrimitive]() {
6196 throw new TypeError('boom');
6197 },
6198 };
6199 
6200 const throwValues = [BigInt(3n), toPrimitive];
6201 
6202 for (const lastModified of throwValues) {
6203 throws(() => new File([], '', { lastModified }), TypeError);
6204 }
6205 }
6206 
6207 {
6208 const valid = [
6209 {
6210 [Symbol.toPrimitive]() {
6211 return 10;
6212 },
6213 },
6214 new Number(10),
6215 10,
6216 ];
6217 
6218 for (const lastModified of valid) {
6219 strictEqual(new File([], '', { lastModified }).lastModified, 10);
6220 }
6221 }
6222 
6223 {
6224 function MyClass() {}
6225 MyClass.prototype.lastModified = 10;
6226 
6227 const file = new File([], '', new MyClass());
6228 strictEqual(file.lastModified, 10);
6229 }
6230 
6231 {
6232 let counter = 0;
6233 new File([], '', {
6234 get lastModified() {
6235 counter++;
6236 return 10;
6237 },
6238 });
6239 strictEqual(counter, 1);
6240 }
6241 },
6242};
6243 
6244// Ref: https://github.com/cloudflare/workerd/issues/2538
6245export const sliceOffsetLimits = {
6246 test() {
6247 // Make sure the second parameter represents the "end" index, not length.
6248 strictEqual(Buffer.from('abcd').utf8Slice(2, 3).toString(), 'c');
6249 // Make sure to handle (end < start) edge case.
6250 strictEqual(Buffer.from('abcd').utf8Slice(1, 0).toString(), '');
6251 },
6252};
6253 
6254// Ref: https://github.com/unjs/unenv/pull/325
6255// Without `.bind(globalThis)` the following tests fail.
6256export const invalidThisTests = {
6257 async test() {
6258 const bufferModule = await import('node:buffer');
6259 strictEqual(bufferModule.btoa('hello'), 'aGVsbG8=');
6260 strictEqual(bufferModule.atob('aGVsbG8='), 'hello');
6261 ok(new bufferModule.File([], 'file'));
6262 ok(new bufferModule.Blob([]));
6263 },
6264};