authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-04-20 21:45:12-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-04-20 21:45:12-07:00
log74b56501b3ac7421a7ae7bda177b7d1b737242dd
treedc7a9ee07e347234a40f25ca113d8dcd2ce5ba41
parent4636a761cbdae7477dcff73ba1d752069adbc9bd

fetch: fix the check against package paths escaping root


1 files changed, 12 insertions(+), 2 deletions(-)

src/Package/Fetch.zig+12-2
......@@ -56,6 +56,9 @@ location_tok: std.zig.Ast.TokenIndex,
5656hash_tok: std.zig.Ast.OptionalTokenIndex,
5757name_tok: std.zig.Ast.TokenIndex,
5858lazy_status: LazyStatus,
59/// Same as `parent_packge_root` except it is unchanged when recursing into
60/// relative file paths (as opposed to URL).
61remote_package_root: Cache.Path,
5962parent_package_root: Cache.Path,
6063parent_manifest_ast: ?*const std.zig.Ast,
6164prog_node: std.Progress.Node,
......@@ -544,8 +547,11 @@ pub fn run(f: *Fetch) RunError!void {
544547 // will already have been resolved to no longer have extra ".." or
545548 // "." components.
546549 assert(job_queue.local_storage != null);
547 assert(pkg_root.root_dir.eql(f.parent_package_root.root_dir));
548 if (!std.mem.startsWith(u8, pkg_root.sub_path, f.parent_package_root.sub_path)) return f.fail(
550 log.debug("checking pkg root \"{s}\" against parent package root \"{s}\"", .{
551 pkg_root.sub_path, f.remote_package_root.sub_path,
552 });
553 assert(pkg_root.root_dir.eql(f.remote_package_root.root_dir));
554 if (!std.mem.startsWith(u8, pkg_root.sub_path, f.remote_package_root.sub_path)) return f.fail(
549555 f.location_tok,
550556 try eb.printString("dependency path outside project: '{f}'", .{pkg_root}),
551557 );
......@@ -591,6 +597,7 @@ pub fn run(f: *Fetch) RunError!void {
591597 log.debug("using fork {f} for {s}", .{ fork.path, fork.manifest.name });
592598 fork.uses += 1;
593599 f.package_root = fork.path;
600 f.remote_package_root = f.package_root;
594601 f.manifest_ast = fork.manifest_ast;
595602 f.manifest = fork.manifest;
596603 f.have_manifest = true;
......@@ -604,6 +611,7 @@ pub fn run(f: *Fetch) RunError!void {
604611 if (package_root.root_dir.handle.access(io, package_root.sub_path, .{})) |_| {
605612 assert(f.lazy_status != .unavailable);
606613 f.package_root = package_root;
614 f.remote_package_root = f.package_root;
607615 try loadManifest(f, f.package_root);
608616 try checkBuildFileExistence(f);
609617 if (!job_queue.recursive) return;
......@@ -782,6 +790,7 @@ fn runResource(
782790 } else {
783791 f.package_root = tmp_directory_path;
784792 }
793 f.remote_package_root = f.package_root;
785794
786795 if (!disable_recompress) {
787796 // Spin off a task to recompress the tarball, with filtered files deleted, into
......@@ -993,6 +1002,7 @@ fn queueJobsForDeps(f: *Fetch) RunError!void {
9931002 .all => .eager,
9941003 },
9951004 .parent_package_root = f.package_root,
1005 .remote_package_root = f.remote_package_root,
9961006 .parent_manifest_ast = &f.manifest_ast,
9971007 .prog_node = f.prog_node,
9981008 .job_queue = f.job_queue,