1'use strict'; 2 3require('../common'); 4const assert = require('assert'); 5 6const b = Buffer.allocUnsafe(1024); 7const c = Buffer.allocUnsafe(512); 8 9let cntr = 0; 10 11{ 12 // copy 512 bytes, from 0 to 512. 13 b.fill(++cntr); 14 c.fill(++cntr); 15 const copied = b.copy(c, 0, 0, 512); 16 assert.strictEqual(copied, 512); 17 for (let i = 0; i < c.length; i++) { 18 assert.strictEqual(c[i], b[i]); 19 } 20} 21 22{ 23 // Current behavior is to coerce values to integers. 24 b.fill(++cntr); 25 c.fill(++cntr); 26 const copied = b.copy(c, '0', '0', '512'); 27 assert.strictEqual(copied, 512); 28 for (let i = 0; i < c.length; i++) { 29 assert.strictEqual(c[i], b[i]); 30 } 31} 32 33{ 34 // Floats will be converted to integers via `Math.floor` 35 b.fill(++cntr); 36 c.fill(++cntr); 37 const copied = b.copy(c, 0, 0, 512.5); 38 assert.strictEqual(copied, 512); 39 for (let i = 0; i < c.length; i++) { 40 assert.strictEqual(c[i], b[i]); 41 } 42} 43 44{ 45 // Copy c into b, without specifying sourceEnd 46 b.fill(++cntr); 47 c.fill(++cntr); 48 const copied = c.copy(b, 0, 0); 49 assert.strictEqual(copied, c.length); 50 for (let i = 0; i < c.length; i++) { 51 assert.strictEqual(b[i], c[i]); 52 } 53} 54 55{ 56 // Copy c into b, without specifying sourceStart 57 b.fill(++cntr); 58 c.fill(++cntr); 59 const copied = c.copy(b, 0); 60 assert.strictEqual(copied, c.length); 61 for (let i = 0; i < c.length; i++) { 62 assert.strictEqual(b[i], c[i]); 63 } 64} 65 66{ 67 // Copied source range greater than source length 68 b.fill(++cntr); 69 c.fill(++cntr); 70 const copied = c.copy(b, 0, 0, c.length + 1); 71 assert.strictEqual(copied, c.length); 72 for (let i = 0; i < c.length; i++) { 73 assert.strictEqual(b[i], c[i]); 74 } 75} 76 77{ 78 // Copy longer buffer b to shorter c without targetStart 79 b.fill(++cntr); 80 c.fill(++cntr); 81 const copied = b.copy(c); 82 assert.strictEqual(copied, c.length); 83 for (let i = 0; i < c.length; i++) { 84 assert.strictEqual(c[i], b[i]); 85 } 86} 87 88{ 89 // Copy starting near end of b to c 90 b.fill(++cntr); 91 c.fill(++cntr); 92 const copied = b.copy(c, 0, b.length - Math.floor(c.length / 2)); 93 assert.strictEqual(copied, Math.floor(c.length / 2)); 94 for (let i = 0; i < Math.floor(c.length / 2); i++) { 95 assert.strictEqual(c[i], b[b.length - Math.floor(c.length / 2) + i]); 96 } 97 for (let i = Math.floor(c.length / 2) + 1; i < c.length; i++) { 98 assert.strictEqual(c[c.length - 1], c[i]); 99 } 100} 101 102{ 103 // Try to copy 513 bytes, and check we don't overrun c 104 b.fill(++cntr); 105 c.fill(++cntr); 106 const copied = b.copy(c, 0, 0, 513); 107 assert.strictEqual(copied, c.length); 108 for (let i = 0; i < c.length; i++) { 109 assert.strictEqual(c[i], b[i]); 110 } 111} 112 113{ 114 // copy 768 bytes from b into b 115 b.fill(++cntr); 116 b.fill(++cntr, 256); 117 const copied = b.copy(b, 0, 256, 1024); 118 assert.strictEqual(copied, 768); 119 for (let i = 0; i < b.length; i++) { 120 assert.strictEqual(b[i], cntr); 121 } 122} 123 124// Copy string longer than buffer length (failure will segfault) 125const bb = Buffer.allocUnsafe(10); 126bb.fill('hello crazy world'); 127 128 129// Try to copy from before the beginning of b. Should not throw. 130b.copy(c, 0, 100, 10); 131 132// Throw with invalid source type 133assert.throws( 134 () => Buffer.prototype.copy.call(0), 135 { 136 code: 'ERR_INVALID_ARG_TYPE', 137 name: 'TypeError', 138 } 139); 140 141// Copy throws at negative targetStart 142assert.throws( 143 () => Buffer.allocUnsafe(5).copy(Buffer.allocUnsafe(5), -1, 0), 144 { 145 code: 'ERR_OUT_OF_RANGE', 146 name: 'RangeError', 147 message: 'The value of "targetStart" is out of range. ' + 148 'It must be >= 0. Received -1' 149 } 150); 151 152// Copy throws at negative sourceStart 153assert.throws( 154 () => Buffer.allocUnsafe(5).copy(Buffer.allocUnsafe(5), 0, -1), 155 { 156 code: 'ERR_OUT_OF_RANGE', 157 name: 'RangeError', 158 message: 'The value of "sourceStart" is out of range. ' + 159 'It must be >= 0. Received -1' 160 } 161); 162 163{ 164 // Check sourceEnd resets to targetEnd if former is greater than the latter 165 b.fill(++cntr); 166 c.fill(++cntr); 167 b.copy(c, 0, 0, 1025); 168 for (let i = 0; i < c.length; i++) { 169 assert.strictEqual(c[i], b[i]); 170 } 171} 172 173// Throw with negative sourceEnd 174assert.throws( 175 () => b.copy(c, 0, 0, -1), 176 { 177 code: 'ERR_OUT_OF_RANGE', 178 name: 'RangeError', 179 message: 'The value of "sourceEnd" is out of range. ' + 180 'It must be >= 0. Received -1' 181 } 182); 183 184// When sourceStart is greater than sourceEnd, zero copied 185assert.strictEqual(b.copy(c, 0, 100, 10), 0); 186 187// When targetStart > targetLength, zero copied 188assert.strictEqual(b.copy(c, 512, 0, 10), 0); 189 190// Test that the `target` can be a Uint8Array. 191{ 192 const d = new Uint8Array(c); 193 // copy 512 bytes, from 0 to 512. 194 b.fill(++cntr); 195 d.fill(++cntr); 196 const copied = b.copy(d, 0, 0, 512); 197 assert.strictEqual(copied, 512); 198 for (let i = 0; i < d.length; i++) { 199 assert.strictEqual(d[i], b[i]); 200 } 201} 202 203// Test that the source can be a Uint8Array, too. 204{ 205 const e = new Uint8Array(b); 206 // copy 512 bytes, from 0 to 512. 207 e.fill(++cntr); 208 c.fill(++cntr); 209 const copied = Buffer.prototype.copy.call(e, c, 0, 0, 512); 210 assert.strictEqual(copied, 512); 211 for (let i = 0; i < c.length; i++) { 212 assert.strictEqual(c[i], e[i]); 213 } 214} 215 216// https://github.com/nodejs/node/issues/23668: Do not crash for invalid input. 217c.fill('c'); 218b.copy(c, 'not a valid offset'); 219// Make sure this acted like a regular copy with `0` offset. 220assert.deepStrictEqual(c, b.slice(0, c.length)); 221 222{ 223 c.fill('C'); 224 assert.throws(() => { 225 b.copy(c, { [Symbol.toPrimitive]() { throw new Error('foo'); } }); 226 }, /foo/); 227 // No copying took place: 228 assert.deepStrictEqual(c.toString(), 'C'.repeat(c.length)); 229} 230