Skip to content

node:path: validate path.relative arguments on compiled paths #2995

Description

@andrewtdiz

Summary

Node path.relative(from, to) requires both arguments to be strings and throws TypeError ERR_INVALID_ARG_TYPE when either argument is not a string. Perry's dynamic native dispatch validates those arguments, but the compiled fast path lowers path.relative() directly to runtime helpers that silently treat invalid string pointers as empty strings.

Node 25.9.0 behavior

const path = require("node:path");

for (const args of [[1, "x"], ["x", 1], [null, "x"], ["x", undefined]]) {
  try { path.relative(...args); }
  catch (err) { console.log(err.name, err.code); }
}
// TypeError ERR_INVALID_ARG_TYPE for every case

The same validation applies to path.posix.relative() and path.win32.relative().

Perry source evidence

  • crates/perry-runtime/src/object/native_module_dispatch.rs uses require_path_str_ptr(0) / require_path_str_ptr(1) for dynamic path.posix.relative and path.win32.relative, so that path is guarded.
  • crates/perry-hir/src/lower/expr_call/module_static.rs, globals.rs, and nested_namespace.rs lower recognized path.relative(...) calls with two arguments to Expr::PathRelative / win32 method expressions without adding argument validation.
  • crates/perry-codegen/src/expr/instance_misc1.rs lowers Expr::PathRelative by unboxing both operands and calling js_path_relative(from, to) directly.
  • crates/perry-runtime/src/path.rs::js_path_relative() reads both inputs with string_from_header(...).unwrap_or_default(); js_path_win32_relative() does the same. Invalid/non-string operands therefore become "" instead of throwing.

Expected

All lowering paths for path.relative(), path.posix.relative(), and path.win32.relative() should perform the same string validation as dynamic dispatch and throw TypeError ERR_INVALID_ARG_TYPE for either non-string argument.

Duplicate checks

  • path.relative non-string type error
  • PathRelative js_path_relative non-string
  • PR search for path.relative type

I did not find an existing issue for the compiled path.relative() validation path.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions