Commit 2a32264533
Changed files (1)
src
Package
src/Package/Fetch.zig
@@ -261,16 +261,22 @@ pub fn run(f: *Fetch) RunError!void {
f.hash_tok,
try eb.addString("path-based dependencies are not hashed"),
);
- if ((std.mem.startsWith(u8, pkg_root.sub_path, "../") or
- std.mem.eql(u8, pkg_root.sub_path, "..")) and
- pkg_root.root_dir.eql(cache_root))
- {
- return f.fail(
- f.location_tok,
- try eb.printString("dependency path outside project: '{}{s}'", .{
- pkg_root.root_dir, pkg_root.sub_path,
- }),
- );
+ // Packages fetched by URL may not use relative paths to escape outside the
+ // fetched package directory from within the package cache.
+ if (pkg_root.root_dir.eql(cache_root)) {
+ // `parent_package_root.sub_path` contains a path like this:
+ // "p/$hash", or
+ // "p/$hash/foo", with possibly more directories after "foo".
+ // We want to fail unless the resolved relative path has a
+ // prefix of "p/$hash/".
+ const digest_len = @typeInfo(Manifest.MultiHashHexDigest).Array.len;
+ const expected_prefix = f.parent_package_root.sub_path[0 .. "p/".len + digest_len];
+ if (!std.mem.startsWith(u8, pkg_root.sub_path, expected_prefix)) {
+ return f.fail(
+ f.location_tok,
+ try eb.printString("dependency path outside project: '{}'", .{pkg_root}),
+ );
+ }
}
f.package_root = pkg_root;
try loadManifest(f, pkg_root);