Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichaƫl Zasso <targos@protonmail.com>2020-09-27 15:34:05 +0300
committerNode.js GitHub Bot <github-bot@iojs.org>2020-09-29 17:23:52 +0300
commit56e36f41aae54fcde72c1cd52fd5792667219b74 (patch)
tree6f348eb379b9df65727e552b3bf4b3530d6a64b0
parent1390574d66c1be8da899d18fe09afc5cc568fb79 (diff)
fs: fix fs.promises.writeFile with typed arrays
Before this change, only the first part of typed arrays which have more than 1 byte per element (e.g. Uint16Array) would be written. This also removes the use of the `slice` method to avoid unnecessary copying the data. Fixes: https://github.com/nodejs/node/issues/35343 PR-URL: https://github.com/nodejs/node/pull/35376 Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Zeyu Yang <himself65@outlook.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
-rw-r--r--lib/internal/fs/promises.js13
-rw-r--r--test/parallel/test-fs-promises-writefile-typedarray.js24
2 files changed, 34 insertions, 3 deletions
diff --git a/lib/internal/fs/promises.js b/lib/internal/fs/promises.js
index a938b382eb1..60a28735a98 100644
--- a/lib/internal/fs/promises.js
+++ b/lib/internal/fs/promises.js
@@ -10,12 +10,13 @@ const kReadFileMaxChunkSize = 2 ** 14;
const kWriteFileMaxChunkSize = 2 ** 14;
const {
+ Error,
MathMax,
MathMin,
NumberIsSafeInteger,
- Symbol,
- Error,
Promise,
+ Symbol,
+ Uint8Array,
} = primordials;
const {
@@ -237,6 +238,8 @@ async function fsCall(fn, handle, ...args) {
}
async function writeFileHandle(filehandle, data) {
+ // `data` could be any kind of typed array.
+ data = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
let remaining = data.length;
if (remaining === 0) return;
do {
@@ -244,7 +247,11 @@ async function writeFileHandle(filehandle, data) {
await write(filehandle, data, 0,
MathMin(kWriteFileMaxChunkSize, data.length));
remaining -= bytesWritten;
- data = data.slice(bytesWritten);
+ data = new Uint8Array(
+ data.buffer,
+ data.byteOffset + bytesWritten,
+ data.byteLength - bytesWritten
+ );
} while (remaining > 0);
}
diff --git a/test/parallel/test-fs-promises-writefile-typedarray.js b/test/parallel/test-fs-promises-writefile-typedarray.js
new file mode 100644
index 00000000000..32d9cffa236
--- /dev/null
+++ b/test/parallel/test-fs-promises-writefile-typedarray.js
@@ -0,0 +1,24 @@
+'use strict';
+
+const common = require('../common');
+const fs = require('fs');
+const fsPromises = fs.promises;
+const path = require('path');
+const tmpdir = require('../common/tmpdir');
+const assert = require('assert');
+const tmpDir = tmpdir.path;
+
+tmpdir.refresh();
+
+const dest = path.resolve(tmpDir, 'tmp.txt');
+// Use a file size larger than `kReadFileMaxChunkSize`.
+const buffer = Buffer.from('012'.repeat(2 ** 14));
+
+(async () => {
+ for (const Constructor of [Uint8Array, Uint16Array, Uint32Array]) {
+ const array = new Constructor(buffer.buffer);
+ await fsPromises.writeFile(dest, array);
+ const data = await fsPromises.readFile(dest);
+ assert.deepStrictEqual(data, buffer);
+ }
+})().then(common.mustCall());