-
Notifications
You must be signed in to change notification settings - Fork 28.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fs: allow writing files with ArrayBuffers #46490
base: main
Are you sure you want to change the base?
Changes from all commits
5802e95
ad09466
d9bd41f
7b5fe63
7f63710
fdad5c2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -38,6 +38,7 @@ const { | |||||
StringPrototypeCharCodeAt, | ||||||
StringPrototypeIndexOf, | ||||||
StringPrototypeSlice, | ||||||
Uint8Array, | ||||||
} = primordials; | ||||||
|
||||||
const { fs: constants } = internalBinding('constants'); | ||||||
|
@@ -56,7 +57,7 @@ const { | |||||
} = constants; | ||||||
|
||||||
const pathModule = require('path'); | ||||||
const { isArrayBufferView } = require('internal/util/types'); | ||||||
const { isArrayBufferView, isArrayBuffer, isSharedArrayBuffer } = require('internal/util/types'); | ||||||
|
||||||
// We need to get the statValues from the binding at the callsite since | ||||||
// it's re-initialized after deserialization. | ||||||
|
@@ -108,6 +109,7 @@ const { | |||||
stringToFlags, | ||||||
stringToSymlinkType, | ||||||
toUnixTimestamp, | ||||||
validateAndNormalizeBufferArray, | ||||||
validateBufferArray, | ||||||
validateCpOptions, | ||||||
validateOffsetLengthRead, | ||||||
|
@@ -819,7 +821,8 @@ function write(fd, buffer, offsetOrOptions, length, position, callback) { | |||||
fd = getValidatedFd(fd); | ||||||
|
||||||
let offset = offsetOrOptions; | ||||||
if (isArrayBufferView(buffer)) { | ||||||
const bufferToWrite = isArrayBuffer(buffer) || isSharedArrayBuffer(buffer) ? new Uint8Array(buffer) : buffer; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ArrayBuffers can have arbitrary length, but TypedArrays are limited to
That's a reason to consider passing the ArrayBuffer into C++ and unwrapping it there, or with a bit more waste, validating the int32 length earlier (currently line 845R) and making this ~ ( Also, V8 is removing the kMaxLength limit sometime soon, which would make this a non-issue. https://bugs.chromium.org/p/v8/issues/detail?id=4153 |
||||||
if (isArrayBufferView(bufferToWrite)) { | ||||||
callback = maybeCallback(callback || position || length || offset); | ||||||
|
||||||
if (typeof offset === 'object') { | ||||||
|
@@ -888,6 +891,9 @@ function writeSync(fd, buffer, offsetOrOptions, length, position) { | |||||
let result; | ||||||
|
||||||
let offset = offsetOrOptions; | ||||||
if (isArrayBuffer(buffer) || isSharedArrayBuffer(buffer)) { | ||||||
buffer = new Uint8Array(buffer); | ||||||
} | ||||||
if (isArrayBufferView(buffer)) { | ||||||
if (typeof offset === 'object') { | ||||||
({ | ||||||
|
@@ -940,7 +946,7 @@ function writev(fd, buffers, position, callback) { | |||||
} | ||||||
|
||||||
fd = getValidatedFd(fd); | ||||||
validateBufferArray(buffers); | ||||||
const buffersToWrite = validateAndNormalizeBufferArray(buffers); | ||||||
callback = maybeCallback(callback || position); | ||||||
|
||||||
if (buffers.length === 0) { | ||||||
|
@@ -954,7 +960,7 @@ function writev(fd, buffers, position, callback) { | |||||
if (typeof position !== 'number') | ||||||
position = null; | ||||||
|
||||||
return binding.writeBuffers(fd, buffers, position, req); | ||||||
return binding.writeBuffers(fd, buffersToWrite, position, req); | ||||||
} | ||||||
|
||||||
ObjectDefineProperty(writev, kCustomPromisifyArgsSymbol, { | ||||||
|
@@ -973,7 +979,7 @@ ObjectDefineProperty(writev, kCustomPromisifyArgsSymbol, { | |||||
*/ | ||||||
function writevSync(fd, buffers, position) { | ||||||
fd = getValidatedFd(fd); | ||||||
validateBufferArray(buffers); | ||||||
buffers = validateAndNormalizeBufferArray(buffers); | ||||||
|
||||||
if (buffers.length === 0) { | ||||||
return 0; | ||||||
|
@@ -2163,7 +2169,7 @@ function writeAll(fd, isUserFd, buffer, offset, length, signal, callback) { | |||||
/** | ||||||
* Asynchronously writes data to the file. | ||||||
* @param {string | Buffer | URL | number} path | ||||||
* @param {string | Buffer | TypedArray | DataView} data | ||||||
* @param {string | Buffer | TypedArray | DataView | ArrayBuffer} data | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
* @param {{ | ||||||
* encoding?: string | null; | ||||||
* mode?: number; | ||||||
|
@@ -2178,6 +2184,10 @@ function writeFile(path, data, options, callback) { | |||||
options = getOptions(options, { encoding: 'utf8', mode: 0o666, flag: 'w' }); | ||||||
const flag = options.flag || 'w'; | ||||||
|
||||||
if (isArrayBuffer(data) || isSharedArrayBuffer(data)) { | ||||||
data = new Uint8Array(data); | ||||||
} | ||||||
|
||||||
if (!isArrayBufferView(data)) { | ||||||
validateStringAfterArrayBufferView(data, 'data'); | ||||||
data = Buffer.from(data, options.encoding || 'utf8'); | ||||||
|
@@ -2207,7 +2217,7 @@ function writeFile(path, data, options, callback) { | |||||
/** | ||||||
* Synchronously writes data to the file. | ||||||
* @param {string | Buffer | URL | number} path | ||||||
* @param {string | Buffer | TypedArray | DataView} data | ||||||
* @param {string | Buffer | TypedArray | DataView | ArrayBuffer} data | ||||||
* @param {{ | ||||||
* encoding?: string | null; | ||||||
* mode?: number; | ||||||
|
@@ -2218,6 +2228,10 @@ function writeFile(path, data, options, callback) { | |||||
function writeFileSync(path, data, options) { | ||||||
options = getOptions(options, { encoding: 'utf8', mode: 0o666, flag: 'w' }); | ||||||
|
||||||
if (isArrayBuffer(data) || isSharedArrayBuffer(data)) { | ||||||
data = new Uint8Array(data); | ||||||
} | ||||||
|
||||||
if (!isArrayBufferView(data)) { | ||||||
validateStringAfterArrayBufferView(data, 'data'); | ||||||
data = Buffer.from(data, options.encoding || 'utf8'); | ||||||
|
@@ -2244,7 +2258,7 @@ function writeFileSync(path, data, options) { | |||||
/** | ||||||
* Asynchronously appends data to a file. | ||||||
* @param {string | Buffer | URL | number} path | ||||||
* @param {string | Buffer} data | ||||||
* @param {string | Buffer | ArrayBuffer} data | ||||||
* @param {{ | ||||||
* encoding?: string | null; | ||||||
* mode?: number; | ||||||
|
@@ -2270,7 +2284,7 @@ function appendFile(path, data, options, callback) { | |||||
/** | ||||||
* Synchronously appends data to a file. | ||||||
* @param {string | Buffer | URL | number} path | ||||||
* @param {string | Buffer} data | ||||||
* @param {string | Buffer | ArrayBuffer} data | ||||||
* @param {{ | ||||||
* encoding?: string | null; | ||||||
* mode?: number; | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Support of
SharedArrayBuffer
should be documented