11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst common = require('../common'); 41cb0ef41Sopenharmony_ciconst assert = require('assert'); 51cb0ef41Sopenharmony_ci 61cb0ef41Sopenharmony_ci[-1, 10].forEach((offset) => { 71cb0ef41Sopenharmony_ci assert.throws( 81cb0ef41Sopenharmony_ci () => Buffer.alloc(9).write('foo', offset), 91cb0ef41Sopenharmony_ci { 101cb0ef41Sopenharmony_ci code: 'ERR_OUT_OF_RANGE', 111cb0ef41Sopenharmony_ci name: 'RangeError', 121cb0ef41Sopenharmony_ci message: 'The value of "offset" is out of range. ' + 131cb0ef41Sopenharmony_ci `It must be >= 0 && <= 9. Received ${offset}` 141cb0ef41Sopenharmony_ci } 151cb0ef41Sopenharmony_ci ); 161cb0ef41Sopenharmony_ci}); 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_ciconst resultMap = new Map([ 191cb0ef41Sopenharmony_ci ['utf8', Buffer.from([102, 111, 111, 0, 0, 0, 0, 0, 0])], 201cb0ef41Sopenharmony_ci ['ucs2', Buffer.from([102, 0, 111, 0, 111, 0, 0, 0, 0])], 211cb0ef41Sopenharmony_ci ['ascii', Buffer.from([102, 111, 111, 0, 0, 0, 0, 0, 0])], 221cb0ef41Sopenharmony_ci ['latin1', Buffer.from([102, 111, 111, 0, 0, 0, 0, 0, 0])], 231cb0ef41Sopenharmony_ci ['binary', Buffer.from([102, 111, 111, 0, 0, 0, 0, 0, 0])], 241cb0ef41Sopenharmony_ci ['utf16le', Buffer.from([102, 0, 111, 0, 111, 0, 0, 0, 0])], 251cb0ef41Sopenharmony_ci ['base64', Buffer.from([102, 111, 111, 0, 0, 0, 0, 0, 0])], 261cb0ef41Sopenharmony_ci ['base64url', Buffer.from([102, 111, 111, 0, 0, 0, 0, 0, 0])], 271cb0ef41Sopenharmony_ci ['hex', Buffer.from([102, 111, 111, 0, 0, 0, 0, 0, 0])], 281cb0ef41Sopenharmony_ci]); 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_ci// utf8, ucs2, ascii, latin1, utf16le 311cb0ef41Sopenharmony_ciconst encodings = ['utf8', 'utf-8', 'ucs2', 'ucs-2', 'ascii', 'latin1', 321cb0ef41Sopenharmony_ci 'binary', 'utf16le', 'utf-16le']; 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ciencodings 351cb0ef41Sopenharmony_ci .reduce((es, e) => es.concat(e, e.toUpperCase()), []) 361cb0ef41Sopenharmony_ci .forEach((encoding) => { 371cb0ef41Sopenharmony_ci const buf = Buffer.alloc(9); 381cb0ef41Sopenharmony_ci const len = Buffer.byteLength('foo', encoding); 391cb0ef41Sopenharmony_ci assert.strictEqual(buf.write('foo', 0, len, encoding), len); 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ci if (encoding.includes('-')) 421cb0ef41Sopenharmony_ci encoding = encoding.replace('-', ''); 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_ci assert.deepStrictEqual(buf, resultMap.get(encoding.toLowerCase())); 451cb0ef41Sopenharmony_ci }); 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ci// base64 481cb0ef41Sopenharmony_ci['base64', 'BASE64', 'base64url', 'BASE64URL'].forEach((encoding) => { 491cb0ef41Sopenharmony_ci const buf = Buffer.alloc(9); 501cb0ef41Sopenharmony_ci const len = Buffer.byteLength('Zm9v', encoding); 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ci assert.strictEqual(buf.write('Zm9v', 0, len, encoding), len); 531cb0ef41Sopenharmony_ci assert.deepStrictEqual(buf, resultMap.get(encoding.toLowerCase())); 541cb0ef41Sopenharmony_ci}); 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ci// hex 571cb0ef41Sopenharmony_ci['hex', 'HEX'].forEach((encoding) => { 581cb0ef41Sopenharmony_ci const buf = Buffer.alloc(9); 591cb0ef41Sopenharmony_ci const len = Buffer.byteLength('666f6f', encoding); 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ci assert.strictEqual(buf.write('666f6f', 0, len, encoding), len); 621cb0ef41Sopenharmony_ci assert.deepStrictEqual(buf, resultMap.get(encoding.toLowerCase())); 631cb0ef41Sopenharmony_ci}); 641cb0ef41Sopenharmony_ci 651cb0ef41Sopenharmony_ci// Invalid encodings 661cb0ef41Sopenharmony_cifor (let i = 1; i < 10; i++) { 671cb0ef41Sopenharmony_ci const encoding = String(i).repeat(i); 681cb0ef41Sopenharmony_ci const error = common.expectsError({ 691cb0ef41Sopenharmony_ci code: 'ERR_UNKNOWN_ENCODING', 701cb0ef41Sopenharmony_ci name: 'TypeError', 711cb0ef41Sopenharmony_ci message: `Unknown encoding: ${encoding}` 721cb0ef41Sopenharmony_ci }); 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_ci assert.ok(!Buffer.isEncoding(encoding)); 751cb0ef41Sopenharmony_ci assert.throws(() => Buffer.alloc(9).write('foo', encoding), error); 761cb0ef41Sopenharmony_ci} 771cb0ef41Sopenharmony_ci 781cb0ef41Sopenharmony_ci// UCS-2 overflow CVE-2018-12115 791cb0ef41Sopenharmony_cifor (let i = 1; i < 4; i++) { 801cb0ef41Sopenharmony_ci // Allocate two Buffers sequentially off the pool. Run more than once in case 811cb0ef41Sopenharmony_ci // we hit the end of the pool and don't get sequential allocations 821cb0ef41Sopenharmony_ci const x = Buffer.allocUnsafe(4).fill(0); 831cb0ef41Sopenharmony_ci const y = Buffer.allocUnsafe(4).fill(1); 841cb0ef41Sopenharmony_ci // Should not write anything, pos 3 doesn't have enough room for a 16-bit char 851cb0ef41Sopenharmony_ci assert.strictEqual(x.write('ыыыыыы', 3, 'ucs2'), 0); 861cb0ef41Sopenharmony_ci // CVE-2018-12115 experienced via buffer overrun to next block in the pool 871cb0ef41Sopenharmony_ci assert.strictEqual(Buffer.compare(y, Buffer.alloc(4, 1)), 0); 881cb0ef41Sopenharmony_ci} 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_ci// Should not write any data when there is no space for 16-bit chars 911cb0ef41Sopenharmony_ciconst z = Buffer.alloc(4, 0); 921cb0ef41Sopenharmony_ciassert.strictEqual(z.write('\u0001', 3, 'ucs2'), 0); 931cb0ef41Sopenharmony_ciassert.strictEqual(Buffer.compare(z, Buffer.alloc(4, 0)), 0); 941cb0ef41Sopenharmony_ci// Make sure longer strings are written up to the buffer end. 951cb0ef41Sopenharmony_ciassert.strictEqual(z.write('abcd', 2), 2); 961cb0ef41Sopenharmony_ciassert.deepStrictEqual([...z], [0, 0, 0x61, 0x62]); 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_ci// Large overrun could corrupt the process 991cb0ef41Sopenharmony_ciassert.strictEqual(Buffer.alloc(4) 1001cb0ef41Sopenharmony_ci .write('ыыыыыы'.repeat(100), 3, 'utf16le'), 0); 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci{ 1031cb0ef41Sopenharmony_ci // .write() does not affect the byte after the written-to slice of the Buffer. 1041cb0ef41Sopenharmony_ci // Refs: https://github.com/nodejs/node/issues/26422 1051cb0ef41Sopenharmony_ci const buf = Buffer.alloc(8); 1061cb0ef41Sopenharmony_ci assert.strictEqual(buf.write('ыы', 1, 'utf16le'), 4); 1071cb0ef41Sopenharmony_ci assert.deepStrictEqual([...buf], [0, 0x4b, 0x04, 0x4b, 0x04, 0, 0, 0]); 1081cb0ef41Sopenharmony_ci} 109