summaryrefslogtreecommitdiff
path: root/ext/node
diff options
context:
space:
mode:
Diffstat (limited to 'ext/node')
-rw-r--r--ext/node/polyfills/_fs/_fs_read.ts4
-rw-r--r--ext/node/polyfills/_fs/_fs_write.mjs6
-rw-r--r--ext/node/polyfills/_fs/_fs_writeFile.ts20
-rw-r--r--ext/node/polyfills/_stream.mjs23
-rw-r--r--ext/node/polyfills/internal/buffer.mjs31
-rw-r--r--ext/node/polyfills/internal/cli_table.ts5
-rw-r--r--ext/node/polyfills/internal/fs/utils.mjs31
-rw-r--r--ext/node/polyfills/internal/validators.mjs15
-rw-r--r--ext/node/polyfills/path/_util.ts6
-rw-r--r--ext/node/polyfills/url.ts28
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;
}