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 } 159); 160 161// Copy throws if sourceStart is greater than length of source 162assert.throws( 163 () => Buffer.allocUnsafe(5).copy(Buffer.allocUnsafe(5), 0, 100), 164 { 165 code: 'ERR_OUT_OF_RANGE', 166 name: 'RangeError', 167 } 168); 169 170{ 171 // Check sourceEnd resets to targetEnd if former is greater than the latter 172 b.fill(++cntr); 173 c.fill(++cntr); 174 b.copy(c, 0, 0, 1025); 175 for (let i = 0; i < c.length; i++) { 176 assert.strictEqual(c[i], b[i]); 177 } 178} 179 180// Throw with negative sourceEnd 181assert.throws( 182 () => b.copy(c, 0, 0, -1), 183 { 184 code: 'ERR_OUT_OF_RANGE', 185 name: 'RangeError', 186 message: 'The value of "sourceEnd" is out of range. ' + 187 'It must be >= 0. Received -1' 188 } 189); 190 191// When sourceStart is greater than sourceEnd, zero copied 192assert.strictEqual(b.copy(c, 0, 100, 10), 0); 193 194// When targetStart > targetLength, zero copied 195assert.strictEqual(b.copy(c, 512, 0, 10), 0); 196 197// Test that the `target` can be a Uint8Array. 198{ 199 const d = new Uint8Array(c); 200 // copy 512 bytes, from 0 to 512. 201 b.fill(++cntr); 202 d.fill(++cntr); 203 const copied = b.copy(d, 0, 0, 512); 204 assert.strictEqual(copied, 512); 205 for (let i = 0; i < d.length; i++) { 206 assert.strictEqual(d[i], b[i]); 207 } 208} 209 210// Test that the source can be a Uint8Array, too. 211{ 212 const e = new Uint8Array(b); 213 // copy 512 bytes, from 0 to 512. 214 e.fill(++cntr); 215 c.fill(++cntr); 216 const copied = Buffer.prototype.copy.call(e, c, 0, 0, 512); 217 assert.strictEqual(copied, 512); 218 for (let i = 0; i < c.length; i++) { 219 assert.strictEqual(c[i], e[i]); 220 } 221} 222 223// https://github.com/nodejs/node/issues/23668: Do not crash for invalid input. 224c.fill('c'); 225b.copy(c, 'not a valid offset'); 226// Make sure this acted like a regular copy with `0` offset. 227assert.deepStrictEqual(c, b.slice(0, c.length)); 228 229{ 230 c.fill('C'); 231 assert.throws(() => { 232 b.copy(c, { [Symbol.toPrimitive]() { throw new Error('foo'); } }); 233 }, /foo/); 234 // No copying took place: 235 assert.deepStrictEqual(c.toString(), 'C'.repeat(c.length)); 236} 237