1'use strict'; 2 3require('../common'); 4const assert = require('assert'); 5 6// We need to check the following things: 7// - We are correctly resolving big endian (doesn't mean anything for 8 bit) 8// - Correctly resolving little endian (doesn't mean anything for 8 bit) 9// - Correctly using the offsets 10// - Correctly interpreting values that are beyond the signed range as unsigned 11 12{ // OOB 13 const data = Buffer.alloc(8); 14 ['UInt8', 'UInt16BE', 'UInt16LE', 'UInt32BE', 'UInt32LE'].forEach((fn) => { 15 16 // Verify that default offset works fine. 17 data[`write${fn}`](23, undefined); 18 data[`write${fn}`](23); 19 20 ['', '0', null, {}, [], () => {}, true, false].forEach((o) => { 21 assert.throws( 22 () => data[`write${fn}`](23, o), 23 { code: 'ERR_INVALID_ARG_TYPE' }); 24 }); 25 26 [NaN, Infinity, -1, 1.01].forEach((o) => { 27 assert.throws( 28 () => data[`write${fn}`](23, o), 29 { code: 'ERR_OUT_OF_RANGE' }); 30 }); 31 }); 32} 33 34{ // Test 8 bit 35 const data = Buffer.alloc(4); 36 37 data.writeUInt8(23, 0); 38 data.writeUInt8(23, 1); 39 data.writeUInt8(23, 2); 40 data.writeUInt8(23, 3); 41 assert.ok(data.equals(new Uint8Array([23, 23, 23, 23]))); 42 43 data.writeUInt8(23, 0); 44 data.writeUInt8(23, 1); 45 data.writeUInt8(23, 2); 46 data.writeUInt8(23, 3); 47 assert.ok(data.equals(new Uint8Array([23, 23, 23, 23]))); 48 49 data.writeUInt8(255, 0); 50 assert.strictEqual(data[0], 255); 51 52 data.writeUInt8(255, 0); 53 assert.strictEqual(data[0], 255); 54} 55 56// Test 16 bit 57{ 58 let value = 0x2343; 59 const data = Buffer.alloc(4); 60 61 data.writeUInt16BE(value, 0); 62 assert.ok(data.equals(new Uint8Array([0x23, 0x43, 0, 0]))); 63 64 data.writeUInt16BE(value, 1); 65 assert.ok(data.equals(new Uint8Array([0x23, 0x23, 0x43, 0]))); 66 67 data.writeUInt16BE(value, 2); 68 assert.ok(data.equals(new Uint8Array([0x23, 0x23, 0x23, 0x43]))); 69 70 data.writeUInt16LE(value, 0); 71 assert.ok(data.equals(new Uint8Array([0x43, 0x23, 0x23, 0x43]))); 72 73 data.writeUInt16LE(value, 1); 74 assert.ok(data.equals(new Uint8Array([0x43, 0x43, 0x23, 0x43]))); 75 76 data.writeUInt16LE(value, 2); 77 assert.ok(data.equals(new Uint8Array([0x43, 0x43, 0x43, 0x23]))); 78 79 value = 0xff80; 80 data.writeUInt16LE(value, 0); 81 assert.ok(data.equals(new Uint8Array([0x80, 0xff, 0x43, 0x23]))); 82 83 data.writeUInt16BE(value, 0); 84 assert.ok(data.equals(new Uint8Array([0xff, 0x80, 0x43, 0x23]))); 85 86 value = 0xfffff; 87 ['writeUInt16BE', 'writeUInt16LE'].forEach((fn) => { 88 assert.throws( 89 () => data[fn](value, 0), 90 { 91 code: 'ERR_OUT_OF_RANGE', 92 message: 'The value of "value" is out of range. ' + 93 `It must be >= 0 and <= 65535. Received ${value}` 94 } 95 ); 96 }); 97} 98 99// Test 32 bit 100{ 101 const data = Buffer.alloc(6); 102 const value = 0xe7f90a6d; 103 104 data.writeUInt32BE(value, 0); 105 assert.ok(data.equals(new Uint8Array([0xe7, 0xf9, 0x0a, 0x6d, 0, 0]))); 106 107 data.writeUInt32BE(value, 1); 108 assert.ok(data.equals(new Uint8Array([0xe7, 0xe7, 0xf9, 0x0a, 0x6d, 0]))); 109 110 data.writeUInt32BE(value, 2); 111 assert.ok(data.equals(new Uint8Array([0xe7, 0xe7, 0xe7, 0xf9, 0x0a, 0x6d]))); 112 113 data.writeUInt32LE(value, 0); 114 assert.ok(data.equals(new Uint8Array([0x6d, 0x0a, 0xf9, 0xe7, 0x0a, 0x6d]))); 115 116 data.writeUInt32LE(value, 1); 117 assert.ok(data.equals(new Uint8Array([0x6d, 0x6d, 0x0a, 0xf9, 0xe7, 0x6d]))); 118 119 data.writeUInt32LE(value, 2); 120 assert.ok(data.equals(new Uint8Array([0x6d, 0x6d, 0x6d, 0x0a, 0xf9, 0xe7]))); 121} 122 123// Test 48 bit 124{ 125 const value = 0x1234567890ab; 126 const data = Buffer.allocUnsafe(6); 127 data.writeUIntBE(value, 0, 6); 128 assert.ok(data.equals(new Uint8Array([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]))); 129 130 data.writeUIntLE(value, 0, 6); 131 assert.ok(data.equals(new Uint8Array([0xab, 0x90, 0x78, 0x56, 0x34, 0x12]))); 132} 133 134// Test UInt 135{ 136 const data = Buffer.alloc(8); 137 let val = 0x100; 138 139 // Check byteLength. 140 ['writeUIntBE', 'writeUIntLE'].forEach((fn) => { 141 ['', '0', null, {}, [], () => {}, true, false, undefined].forEach((bl) => { 142 assert.throws( 143 () => data[fn](23, 0, bl), 144 { code: 'ERR_INVALID_ARG_TYPE' }); 145 }); 146 147 [Infinity, -1].forEach((byteLength) => { 148 assert.throws( 149 () => data[fn](23, 0, byteLength), 150 { 151 code: 'ERR_OUT_OF_RANGE', 152 message: 'The value of "byteLength" is out of range. ' + 153 `It must be >= 1 and <= 6. Received ${byteLength}` 154 } 155 ); 156 }); 157 158 [NaN, 1.01].forEach((byteLength) => { 159 assert.throws( 160 () => data[fn](42, 0, byteLength), 161 { 162 code: 'ERR_OUT_OF_RANGE', 163 name: 'RangeError', 164 message: 'The value of "byteLength" is out of range. ' + 165 `It must be an integer. Received ${byteLength}` 166 }); 167 }); 168 }); 169 170 // Test 1 to 6 bytes. 171 for (let i = 1; i <= 6; i++) { 172 const range = i < 5 ? `= ${val - 1}` : ` 2 ** ${i * 8}`; 173 const received = i > 4 ? 174 String(val).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1_') : 175 val; 176 ['writeUIntBE', 'writeUIntLE'].forEach((fn) => { 177 assert.throws(() => { 178 data[fn](val, 0, i); 179 }, { 180 code: 'ERR_OUT_OF_RANGE', 181 name: 'RangeError', 182 message: 'The value of "value" is out of range. ' + 183 `It must be >= 0 and <${range}. Received ${received}` 184 }); 185 186 ['', '0', null, {}, [], () => {}, true, false].forEach((o) => { 187 assert.throws( 188 () => data[fn](23, o, i), 189 { 190 code: 'ERR_INVALID_ARG_TYPE', 191 name: 'TypeError' 192 }); 193 }); 194 195 [Infinity, -1, -4294967295].forEach((offset) => { 196 assert.throws( 197 () => data[fn](val - 1, offset, i), 198 { 199 code: 'ERR_OUT_OF_RANGE', 200 name: 'RangeError', 201 message: 'The value of "offset" is out of range. ' + 202 `It must be >= 0 and <= ${8 - i}. Received ${offset}` 203 }); 204 }); 205 206 [NaN, 1.01].forEach((offset) => { 207 assert.throws( 208 () => data[fn](val - 1, offset, i), 209 { 210 code: 'ERR_OUT_OF_RANGE', 211 name: 'RangeError', 212 message: 'The value of "offset" is out of range. ' + 213 `It must be an integer. Received ${offset}` 214 }); 215 }); 216 }); 217 218 val *= 0x100; 219 } 220} 221 222for (const fn of [ 223 'UInt8', 'UInt16LE', 'UInt16BE', 'UInt32LE', 'UInt32BE', 'UIntLE', 'UIntBE', 224 'BigUInt64LE', 'BigUInt64BE', 225]) { 226 const p = Buffer.prototype; 227 const lowerFn = fn.replace(/UInt/, 'Uint'); 228 assert.strictEqual(p[`write${fn}`], p[`write${lowerFn}`]); 229 assert.strictEqual(p[`read${fn}`], p[`read${lowerFn}`]); 230} 231