diff options
Diffstat (limited to 'ext/node/polyfills')
-rw-r--r-- | ext/node/polyfills/_fs/_fs_read.ts | 4 | ||||
-rw-r--r-- | ext/node/polyfills/_fs/_fs_write.mjs | 6 | ||||
-rw-r--r-- | ext/node/polyfills/_fs/_fs_writeFile.ts | 20 | ||||
-rw-r--r-- | ext/node/polyfills/_stream.mjs | 23 | ||||
-rw-r--r-- | ext/node/polyfills/internal/buffer.mjs | 31 | ||||
-rw-r--r-- | ext/node/polyfills/internal/cli_table.ts | 5 | ||||
-rw-r--r-- | ext/node/polyfills/internal/fs/utils.mjs | 31 | ||||
-rw-r--r-- | ext/node/polyfills/internal/validators.mjs | 15 | ||||
-rw-r--r-- | ext/node/polyfills/path/_util.ts | 6 | ||||
-rw-r--r-- | ext/node/polyfills/url.ts | 28 |
10 files changed, 94 insertions, 75 deletions
diff --git a/ext/node/polyfills/_fs/_fs_read.ts b/ext/node/polyfills/_fs/_fs_read.ts index cf0c5e51d..e25f41e76 100644 --- a/ext/node/polyfills/_fs/_fs_read.ts +++ b/ext/node/polyfills/_fs/_fs_read.ts @@ -88,10 +88,6 @@ export function read( if ( !(opt.buffer instanceof Buffer) && !(opt.buffer instanceof Uint8Array) ) { - if (opt.buffer === null) { - // @ts-ignore: Intentionally create TypeError for passing test-fs-read.js#L87 - length = opt.buffer.byteLength; - } throw new ERR_INVALID_ARG_TYPE("buffer", [ "Buffer", "TypedArray", diff --git a/ext/node/polyfills/_fs/_fs_write.mjs b/ext/node/polyfills/_fs/_fs_write.mjs index aa23805bf..1ad6ac492 100644 --- a/ext/node/polyfills/_fs/_fs_write.mjs +++ b/ext/node/polyfills/_fs/_fs_write.mjs @@ -13,7 +13,6 @@ import * as io from "ext:deno_io/12_io.js"; import * as fs from "ext:deno_fs/30_fs.js"; import { getValidatedFd, - showStringCoercionDeprecation, validateOffsetLengthWrite, validateStringAfterArrayBufferView, } from "ext:deno_node/internal/fs/utils.mjs"; @@ -114,9 +113,6 @@ export function write(fd, buffer, offset, length, position, callback) { // `fs.write(fd, string[, position[, encoding]], callback)` validateStringAfterArrayBufferView(buffer, "buffer"); - if (typeof buffer !== "string") { - showStringCoercionDeprecation(); - } if (typeof position !== "function") { if (typeof offset === "function") { @@ -128,7 +124,7 @@ export function write(fd, buffer, offset, length, position, callback) { length = "utf-8"; } - const str = String(buffer); + const str = buffer; validateEncoding(str, length); callback = maybeCallback(position); buffer = Buffer.from(str, length); diff --git a/ext/node/polyfills/_fs/_fs_writeFile.ts b/ext/node/polyfills/_fs/_fs_writeFile.ts index 60b31897e..f0014c36d 100644 --- a/ext/node/polyfills/_fs/_fs_writeFile.ts +++ b/ext/node/polyfills/_fs/_fs_writeFile.ts @@ -20,7 +20,6 @@ import { denoErrorToNodeError, } from "ext:deno_node/internal/errors.ts"; import { - showStringCoercionDeprecation, validateStringAfterArrayBufferView, } from "ext:deno_node/internal/fs/utils.mjs"; import { promisify } from "ext:deno_node/internal/util.mjs"; @@ -32,8 +31,7 @@ interface Writer { export function writeFile( pathOrRid: string | number | URL, - // deno-lint-ignore ban-types - data: string | Uint8Array | Object, + data: string | Uint8Array, optOrCallback: Encodings | CallbackWithError | WriteFileOptions | undefined, callback?: CallbackWithError, ) { @@ -61,10 +59,7 @@ export function writeFile( if (!ArrayBuffer.isView(data)) { validateStringAfterArrayBufferView(data, "data"); - if (typeof data !== "string") { - showStringCoercionDeprecation(); - } - data = Buffer.from(String(data), encoding); + data = Buffer.from(data, encoding); } const isRid = typeof pathOrRid === "number"; @@ -101,15 +96,13 @@ export function writeFile( export const writeFilePromise = promisify(writeFile) as ( pathOrRid: string | number | URL, - // deno-lint-ignore ban-types - data: string | Uint8Array | Object, + data: string | Uint8Array, options?: Encodings | WriteFileOptions, ) => Promise<void>; export function writeFileSync( pathOrRid: string | number | URL, - // deno-lint-ignore ban-types - data: string | Uint8Array | Object, + data: string | Uint8Array, options?: Encodings | WriteFileOptions, ) { pathOrRid = pathOrRid instanceof URL ? pathFromURL(pathOrRid) : pathOrRid; @@ -127,10 +120,7 @@ export function writeFileSync( if (!ArrayBuffer.isView(data)) { validateStringAfterArrayBufferView(data, "data"); - if (typeof data !== "string") { - showStringCoercionDeprecation(); - } - data = Buffer.from(String(data), encoding); + data = Buffer.from(data, encoding); } const isRid = typeof pathOrRid === "number"; diff --git a/ext/node/polyfills/_stream.mjs b/ext/node/polyfills/_stream.mjs index 591f8bb51..075705e00 100644 --- a/ext/node/polyfills/_stream.mjs +++ b/ext/node/polyfills/_stream.mjs @@ -3754,7 +3754,14 @@ var require_writable = __commonJS({ this.destroyed = false; const noDecode = !!(options && options.decodeStrings === false); this.decodeStrings = !noDecode; - this.defaultEncoding = options && options.defaultEncoding || "utf8"; + const defaultEncoding = options?.defaultEncoding; + if (defaultEncoding == null) { + this.defaultEncoding = 'utf8'; + } else if (Buffer2.isEncoding(defaultEncoding)) { + this.defaultEncoding = defaultEncoding; + } else { + throw new ERR_UNKNOWN_ENCODING(defaultEncoding); + } this.length = 0; this.writing = false; this.corked = 0; @@ -3845,10 +3852,12 @@ var require_writable = __commonJS({ const state = stream._writableState; if (typeof encoding === "function") { cb = encoding; - encoding = state.defaultEncoding; + // Simulates https://github.com/nodejs/node/commit/dbed0319ac438dcbd6e92483f3280b1dc6767e00 + encoding = state.objectMode ? undefined : state.defaultEncoding; } else { if (!encoding) { - encoding = state.defaultEncoding; + // Simulates https://github.com/nodejs/node/commit/dbed0319ac438dcbd6e92483f3280b1dc6767e00 + encoding = state.objectMode ? undefined : state.defaultEncoding; } else if (encoding !== "buffer" && !Buffer2.isEncoding(encoding)) { throw new ERR_UNKNOWN_ENCODING(encoding); } @@ -4031,7 +4040,7 @@ var require_writable = __commonJS({ } while (count-- > 0) { state.pendingcb--; - cb(); + cb(null); } if (state.destroyed) { errorBuffer(state); @@ -4158,8 +4167,10 @@ var require_writable = __commonJS({ err = new ERR_STREAM_DESTROYED("end"); } if (typeof cb === "function") { - if (err || state.finished) { + if (err) { process.nextTick(cb, err); + } else if (state.finished) { + process.nextTick(cb, null); } else { state[kOnFinished].push(cb); } @@ -4246,7 +4257,7 @@ var require_writable = __commonJS({ state.finished = true; const onfinishCallbacks = state[kOnFinished].splice(0); for (let i = 0; i < onfinishCallbacks.length; i++) { - onfinishCallbacks[i](); + onfinishCallbacks[i](null); } stream.emit("finish"); if (state.autoDestroy) { diff --git a/ext/node/polyfills/internal/buffer.mjs b/ext/node/polyfills/internal/buffer.mjs index 0521c56aa..a051965a3 100644 --- a/ext/node/polyfills/internal/buffer.mjs +++ b/ext/node/polyfills/internal/buffer.mjs @@ -32,7 +32,7 @@ import { import { normalizeEncoding } from "ext:deno_node/internal/util.mjs"; import { validateBuffer } from "ext:deno_node/internal/validators.mjs"; import { isUint8Array } from "ext:deno_node/internal/util/types.ts"; -import { ERR_INVALID_STATE } from "ext:deno_node/internal/errors.ts"; +import { ERR_INVALID_STATE, NodeError } from "ext:deno_node/internal/errors.ts"; import { forgivingBase64Encode, forgivingBase64UrlEncode, @@ -167,10 +167,7 @@ Object.setPrototypeOf(Buffer.prototype, Uint8Array.prototype); Object.setPrototypeOf(Buffer, Uint8Array); function assertSize(size) { - validateNumber(size, "size"); - if (!(size >= 0 && size <= kMaxLength)) { - throw new codes.ERR_INVALID_ARG_VALUE.RangeError("size", size); - } + validateNumber(size, "size", 0, kMaxLength); } function _alloc(size, fill, encoding) { @@ -852,7 +849,14 @@ function _base64Slice(buf, start, end) { const decoder = new TextDecoder(); function _utf8Slice(buf, start, end) { - return decoder.decode(buf.slice(start, end)); + try { + return decoder.decode(buf.slice(start, end)); + } catch (err) { + if (err instanceof TypeError) { + throw new NodeError("ERR_STRING_TOO_LONG", "String too long"); + } + throw err; + } } function _latin1Slice(buf, start, end) { @@ -2297,10 +2301,23 @@ export function boundsError(value, length, type) { ); } -export function validateNumber(value, name) { +export function validateNumber(value, name, min = undefined, max) { if (typeof value !== "number") { throw new codes.ERR_INVALID_ARG_TYPE(name, "number", value); } + + if ( + (min != null && value < min) || (max != null && value > max) || + ((min != null || max != null) && Number.isNaN(value)) + ) { + throw new codes.ERR_OUT_OF_RANGE( + name, + `${min != null ? `>= ${min}` : ""}${ + min != null && max != null ? " && " : "" + }${max != null ? `<= ${max}` : ""}`, + value, + ); + } } function checkInt(value, min, max, buf, offset, byteLength) { diff --git a/ext/node/polyfills/internal/cli_table.ts b/ext/node/polyfills/internal/cli_table.ts index 574081ba4..9826e524f 100644 --- a/ext/node/polyfills/internal/cli_table.ts +++ b/ext/node/polyfills/internal/cli_table.ts @@ -27,11 +27,10 @@ const renderRow = (row: string[], columnWidths: number[]) => { for (let i = 0; i < row.length; i++) { const cell = row[i]; const len = getStringWidth(cell); - const needed = (columnWidths[i] - len) / 2; + const needed = columnWidths[i] - len; // round(needed) + ceil(needed) will always add up to the amount // of spaces we need while also left justifying the output. - out += " ".repeat(needed) + cell + - " ".repeat(Math.ceil(needed)); + out += cell + " ".repeat(Math.ceil(needed)); if (i !== row.length - 1) { out += tableChars.middle; } diff --git a/ext/node/polyfills/internal/fs/utils.mjs b/ext/node/polyfills/internal/fs/utils.mjs index a1823bb32..ec379ed99 100644 --- a/ext/node/polyfills/internal/fs/utils.mjs +++ b/ext/node/polyfills/internal/fs/utils.mjs @@ -23,7 +23,6 @@ import { isUint8Array, } from "ext:deno_node/internal/util/types.ts"; import { once } from "ext:deno_node/internal/util.mjs"; -import { deprecate } from "node:util"; import { toPathIfFileURL } from "ext:deno_node/internal/url.ts"; import { validateAbortSignal, @@ -959,24 +958,13 @@ export const getValidMode = hideStackFrames((mode, type) => { export const validateStringAfterArrayBufferView = hideStackFrames( (buffer, name) => { - if (typeof buffer === "string") { - return; - } - - if ( - typeof buffer === "object" && - buffer !== null && - typeof buffer.toString === "function" && - Object.prototype.hasOwnProperty.call(buffer, "toString") - ) { - return; + if (typeof buffer !== "string") { + throw new ERR_INVALID_ARG_TYPE( + name, + ["string", "Buffer", "TypedArray", "DataView"], + buffer, + ); } - - throw new ERR_INVALID_ARG_TYPE( - name, - ["string", "Buffer", "TypedArray", "DataView"], - buffer, - ); }, ); @@ -1005,12 +993,6 @@ export const constants = { kWriteFileMaxChunkSize, }; -export const showStringCoercionDeprecation = deprecate( - () => {}, - "Implicit coercion of objects with own toString property is deprecated.", - "DEP0162", -); - export default { constants, assertEncoding, @@ -1030,7 +1012,6 @@ export default { preprocessSymlinkDestination, realpathCacheKey, getStatsFromBinding, - showStringCoercionDeprecation, stringToFlags, stringToSymlinkType, Stats, diff --git a/ext/node/polyfills/internal/validators.mjs b/ext/node/polyfills/internal/validators.mjs index d4cd95546..58b1a97d7 100644 --- a/ext/node/polyfills/internal/validators.mjs +++ b/ext/node/polyfills/internal/validators.mjs @@ -171,10 +171,23 @@ function validateString(value, name) { * @param {unknown} value * @param {string} name */ -function validateNumber(value, name) { +function validateNumber(value, name, min = undefined, max) { if (typeof value !== "number") { throw new codes.ERR_INVALID_ARG_TYPE(name, "number", value); } + + if ( + (min != null && value < min) || (max != null && value > max) || + ((min != null || max != null) && Number.isNaN(value)) + ) { + throw new codes.ERR_OUT_OF_RANGE( + name, + `${min != null ? `>= ${min}` : ""}${ + min != null && max != null ? " && " : "" + }${max != null ? `<= ${max}` : ""}`, + value, + ); + } } /** diff --git a/ext/node/polyfills/path/_util.ts b/ext/node/polyfills/path/_util.ts index 7be482965..9248c68ae 100644 --- a/ext/node/polyfills/path/_util.ts +++ b/ext/node/polyfills/path/_util.ts @@ -106,13 +106,17 @@ export function normalizeString( return res; } +function formatExt(ext) { + return ext ? `${ext[0] === "." ? "" : "."}${ext}` : ""; +} + export function _format( sep: string, pathObject: FormatInputPathObject, ): string { const dir: string | undefined = pathObject.dir || pathObject.root; const base: string = pathObject.base || - (pathObject.name || "") + (pathObject.ext || ""); + (pathObject.name || "") + formatExt(pathObject.ext); if (!dir) return base; if (dir === pathObject.root) return dir + base; return dir + sep + base; diff --git a/ext/node/polyfills/url.ts b/ext/node/polyfills/url.ts index 6633334ba..4eeb0381f 100644 --- a/ext/node/polyfills/url.ts +++ b/ext/node/polyfills/url.ts @@ -1352,12 +1352,16 @@ function getPathFromURLPosix(url: URL): string { * setter. * - TAB: The tab character is also stripped out by the `pathname` setter. */ -function encodePathChars(filepath: string): string { +function encodePathChars( + filepath: string, + options: { windows?: boolean }, +): string { + const windows = options.windows; if (filepath.includes("%")) { filepath = filepath.replace(percentRegEx, "%25"); } // In posix, backslash is a valid character in paths: - if (!isWindows && filepath.includes("\\")) { + if (!(windows ?? isWindows) && filepath.includes("\\")) { filepath = filepath.replace(backslashRegEx, "%5C"); } if (filepath.includes("\n")) { @@ -1376,11 +1380,17 @@ function encodePathChars(filepath: string): string { * This function ensures that `filepath` is resolved absolutely, and that the URL control characters are correctly encoded when converting into a File URL. * @see Tested in `parallel/test-url-pathtofileurl.js`. * @param filepath The file path string to convert to a file URL. + * @param options The options. * @returns The file URL object. */ -export function pathToFileURL(filepath: string): URL { +export function pathToFileURL( + filepath: string, + options: { windows?: boolean } = {}, +): URL { + validateString(filepath, "path"); + const windows = options?.windows; const outURL = new URL("file://"); - if (isWindows && filepath.startsWith("\\\\")) { + if ((windows ?? isWindows) && filepath.startsWith("\\\\")) { // UNC path format: \\server\share\resource const paths = filepath.split("\\"); if (paths.length <= 3) { @@ -1400,20 +1410,22 @@ export function pathToFileURL(filepath: string): URL { } outURL.hostname = idnaToASCII(hostname); - outURL.pathname = encodePathChars(paths.slice(3).join("/")); + outURL.pathname = encodePathChars(paths.slice(3).join("/"), { windows }); } else { - let resolved = path.resolve(filepath); + let resolved = (windows ?? isWindows) + ? path.win32.resolve(filepath) + : path.posix.resolve(filepath); // path.resolve strips trailing slashes so we must add them back const filePathLast = filepath.charCodeAt(filepath.length - 1); if ( (filePathLast === CHAR_FORWARD_SLASH || - (isWindows && filePathLast === CHAR_BACKWARD_SLASH)) && + ((windows ?? isWindows) && filePathLast === CHAR_BACKWARD_SLASH)) && resolved[resolved.length - 1] !== path.sep ) { resolved += "/"; } - outURL.pathname = encodePathChars(resolved); + outURL.pathname = encodePathChars(resolved, { windows }); } return outURL; } |