1'use strict'; 2 3// Tests to verify signed integers are correctly written 4 5require('../common'); 6const assert = require('assert'); 7const errorOutOfBounds = { 8 code: 'ERR_OUT_OF_RANGE', 9 name: 'RangeError', 10 message: new RegExp('^The value of "value" is out of range\\. ' + 11 'It must be >= -\\d+ and <= \\d+\\. Received .+$') 12}; 13 14// Test 8 bit 15{ 16 const buffer = Buffer.alloc(2); 17 18 buffer.writeInt8(0x23, 0); 19 buffer.writeInt8(-5, 1); 20 assert.ok(buffer.equals(new Uint8Array([ 0x23, 0xfb ]))); 21 22 /* Make sure we handle min/max correctly */ 23 buffer.writeInt8(0x7f, 0); 24 buffer.writeInt8(-0x80, 1); 25 assert.ok(buffer.equals(new Uint8Array([ 0x7f, 0x80 ]))); 26 27 assert.throws(() => { 28 buffer.writeInt8(0x7f + 1, 0); 29 }, errorOutOfBounds); 30 assert.throws(() => { 31 buffer.writeInt8(-0x80 - 1, 0); 32 }, errorOutOfBounds); 33 34 // Verify that default offset works fine. 35 buffer.writeInt8(23, undefined); 36 buffer.writeInt8(23); 37 38 ['', '0', null, {}, [], () => {}, true, false].forEach((off) => { 39 assert.throws( 40 () => buffer.writeInt8(23, off), 41 { code: 'ERR_INVALID_ARG_TYPE' }); 42 }); 43 44 [NaN, Infinity, -1, 1.01].forEach((off) => { 45 assert.throws( 46 () => buffer.writeInt8(23, off), 47 { code: 'ERR_OUT_OF_RANGE' }); 48 }); 49} 50 51// Test 16 bit 52{ 53 const buffer = Buffer.alloc(4); 54 55 buffer.writeInt16BE(0x0023, 0); 56 buffer.writeInt16LE(0x0023, 2); 57 assert.ok(buffer.equals(new Uint8Array([ 0x00, 0x23, 0x23, 0x00 ]))); 58 59 buffer.writeInt16BE(-5, 0); 60 buffer.writeInt16LE(-5, 2); 61 assert.ok(buffer.equals(new Uint8Array([ 0xff, 0xfb, 0xfb, 0xff ]))); 62 63 buffer.writeInt16BE(-1679, 0); 64 buffer.writeInt16LE(-1679, 2); 65 assert.ok(buffer.equals(new Uint8Array([ 0xf9, 0x71, 0x71, 0xf9 ]))); 66 67 /* Make sure we handle min/max correctly */ 68 buffer.writeInt16BE(0x7fff, 0); 69 buffer.writeInt16BE(-0x8000, 2); 70 assert.ok(buffer.equals(new Uint8Array([ 0x7f, 0xff, 0x80, 0x00 ]))); 71 72 buffer.writeInt16LE(0x7fff, 0); 73 buffer.writeInt16LE(-0x8000, 2); 74 assert.ok(buffer.equals(new Uint8Array([ 0xff, 0x7f, 0x00, 0x80 ]))); 75 76 ['writeInt16BE', 'writeInt16LE'].forEach((fn) => { 77 78 // Verify that default offset works fine. 79 buffer[fn](23, undefined); 80 buffer[fn](23); 81 82 assert.throws(() => { 83 buffer[fn](0x7fff + 1, 0); 84 }, errorOutOfBounds); 85 assert.throws(() => { 86 buffer[fn](-0x8000 - 1, 0); 87 }, errorOutOfBounds); 88 89 ['', '0', null, {}, [], () => {}, true, false].forEach((off) => { 90 assert.throws( 91 () => buffer[fn](23, off), 92 { code: 'ERR_INVALID_ARG_TYPE' }); 93 }); 94 95 [NaN, Infinity, -1, 1.01].forEach((off) => { 96 assert.throws( 97 () => buffer[fn](23, off), 98 { code: 'ERR_OUT_OF_RANGE' }); 99 }); 100 }); 101} 102 103// Test 32 bit 104{ 105 const buffer = Buffer.alloc(8); 106 107 buffer.writeInt32BE(0x23, 0); 108 buffer.writeInt32LE(0x23, 4); 109 assert.ok(buffer.equals(new Uint8Array([ 110 0x00, 0x00, 0x00, 0x23, 0x23, 0x00, 0x00, 0x00, 111 ]))); 112 113 buffer.writeInt32BE(-5, 0); 114 buffer.writeInt32LE(-5, 4); 115 assert.ok(buffer.equals(new Uint8Array([ 116 0xff, 0xff, 0xff, 0xfb, 0xfb, 0xff, 0xff, 0xff, 117 ]))); 118 119 buffer.writeInt32BE(-805306713, 0); 120 buffer.writeInt32LE(-805306713, 4); 121 assert.ok(buffer.equals(new Uint8Array([ 122 0xcf, 0xff, 0xfe, 0xa7, 0xa7, 0xfe, 0xff, 0xcf, 123 ]))); 124 125 /* Make sure we handle min/max correctly */ 126 buffer.writeInt32BE(0x7fffffff, 0); 127 buffer.writeInt32BE(-0x80000000, 4); 128 assert.ok(buffer.equals(new Uint8Array([ 129 0x7f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 130 ]))); 131 132 buffer.writeInt32LE(0x7fffffff, 0); 133 buffer.writeInt32LE(-0x80000000, 4); 134 assert.ok(buffer.equals(new Uint8Array([ 135 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x80, 136 ]))); 137 138 ['writeInt32BE', 'writeInt32LE'].forEach((fn) => { 139 140 // Verify that default offset works fine. 141 buffer[fn](23, undefined); 142 buffer[fn](23); 143 144 assert.throws(() => { 145 buffer[fn](0x7fffffff + 1, 0); 146 }, errorOutOfBounds); 147 assert.throws(() => { 148 buffer[fn](-0x80000000 - 1, 0); 149 }, errorOutOfBounds); 150 151 ['', '0', null, {}, [], () => {}, true, false].forEach((off) => { 152 assert.throws( 153 () => buffer[fn](23, off), 154 { code: 'ERR_INVALID_ARG_TYPE' }); 155 }); 156 157 [NaN, Infinity, -1, 1.01].forEach((off) => { 158 assert.throws( 159 () => buffer[fn](23, off), 160 { code: 'ERR_OUT_OF_RANGE' }); 161 }); 162 }); 163} 164 165// Test 48 bit 166{ 167 const value = 0x1234567890ab; 168 const buffer = Buffer.allocUnsafe(6); 169 buffer.writeIntBE(value, 0, 6); 170 assert.ok(buffer.equals(new Uint8Array([ 171 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 172 ]))); 173 174 buffer.writeIntLE(value, 0, 6); 175 assert.ok(buffer.equals(new Uint8Array([ 176 0xab, 0x90, 0x78, 0x56, 0x34, 0x12, 177 ]))); 178} 179 180// Test Int 181{ 182 const data = Buffer.alloc(8); 183 184 // Check byteLength. 185 ['writeIntBE', 'writeIntLE'].forEach((fn) => { 186 ['', '0', null, {}, [], () => {}, true, false, undefined].forEach((bl) => { 187 assert.throws( 188 () => data[fn](23, 0, bl), 189 { code: 'ERR_INVALID_ARG_TYPE' }); 190 }); 191 192 [Infinity, -1].forEach((byteLength) => { 193 assert.throws( 194 () => data[fn](23, 0, byteLength), 195 { 196 code: 'ERR_OUT_OF_RANGE', 197 message: 'The value of "byteLength" is out of range. ' + 198 `It must be >= 1 and <= 6. Received ${byteLength}` 199 } 200 ); 201 }); 202 203 [NaN, 1.01].forEach((byteLength) => { 204 assert.throws( 205 () => data[fn](42, 0, byteLength), 206 { 207 code: 'ERR_OUT_OF_RANGE', 208 name: 'RangeError', 209 message: 'The value of "byteLength" is out of range. ' + 210 `It must be an integer. Received ${byteLength}` 211 }); 212 }); 213 }); 214 215 // Test 1 to 6 bytes. 216 for (let i = 1; i <= 6; i++) { 217 ['writeIntBE', 'writeIntLE'].forEach((fn) => { 218 const min = -(2 ** (i * 8 - 1)); 219 const max = 2 ** (i * 8 - 1) - 1; 220 let range = `>= ${min} and <= ${max}`; 221 if (i > 4) { 222 range = `>= -(2 ** ${i * 8 - 1}) and < 2 ** ${i * 8 - 1}`; 223 } 224 [min - 1, max + 1].forEach((val) => { 225 const received = i > 4 ? 226 String(val).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1_') : 227 val; 228 assert.throws(() => { 229 data[fn](val, 0, i); 230 }, { 231 code: 'ERR_OUT_OF_RANGE', 232 name: 'RangeError', 233 message: 'The value of "value" is out of range. ' + 234 `It must be ${range}. Received ${received}` 235 }); 236 }); 237 238 ['', '0', null, {}, [], () => {}, true, false, undefined].forEach((o) => { 239 assert.throws( 240 () => data[fn](min, o, i), 241 { 242 code: 'ERR_INVALID_ARG_TYPE', 243 name: 'TypeError' 244 }); 245 }); 246 247 [Infinity, -1, -4294967295].forEach((offset) => { 248 assert.throws( 249 () => data[fn](min, offset, i), 250 { 251 code: 'ERR_OUT_OF_RANGE', 252 name: 'RangeError', 253 message: 'The value of "offset" is out of range. ' + 254 `It must be >= 0 and <= ${8 - i}. Received ${offset}` 255 }); 256 }); 257 258 [NaN, 1.01].forEach((offset) => { 259 assert.throws( 260 () => data[fn](max, offset, i), 261 { 262 code: 'ERR_OUT_OF_RANGE', 263 name: 'RangeError', 264 message: 'The value of "offset" is out of range. ' + 265 `It must be an integer. Received ${offset}` 266 }); 267 }); 268 }); 269 } 270} 271