| ... | ... | @@ -261,16 +261,22 @@ pub fn run(f: *Fetch) RunError!void { |
| 261 | 261 | f.hash_tok, |
| 262 | 262 | try eb.addString("path-based dependencies are not hashed"), |
| 263 | 263 | ); |
| 264 | | if ((std.mem.startsWith(u8, pkg_root.sub_path, "../") or |
| 265 | | std.mem.eql(u8, pkg_root.sub_path, "..")) and |
| 266 | | pkg_root.root_dir.eql(cache_root)) |
| 267 | | { |
| 268 | | return f.fail( |
| 269 | | f.location_tok, |
| 270 | | try eb.printString("dependency path outside project: '{}{s}'", .{ |
| 271 | | pkg_root.root_dir, pkg_root.sub_path, |
| 272 | | }), |
| 273 | | ); |
| 264 | // Packages fetched by URL may not use relative paths to escape outside the |
| 265 | // fetched package directory from within the package cache. |
| 266 | if (pkg_root.root_dir.eql(cache_root)) { |
| 267 | // `parent_package_root.sub_path` contains a path like this: |
| 268 | // "p/$hash", or |
| 269 | // "p/$hash/foo", with possibly more directories after "foo". |
| 270 | // We want to fail unless the resolved relative path has a |
| 271 | // prefix of "p/$hash/". |
| 272 | const digest_len = @typeInfo(Manifest.MultiHashHexDigest).Array.len; |
| 273 | const expected_prefix = f.parent_package_root.sub_path[0 .. "p/".len + digest_len]; |
| 274 | if (!std.mem.startsWith(u8, pkg_root.sub_path, expected_prefix)) { |
| 275 | return f.fail( |
| 276 | f.location_tok, |
| 277 | try eb.printString("dependency path outside project: '{}'", .{pkg_root}), |
| 278 | ); |
| 279 | } |
| 274 | 280 | } |
| 275 | 281 | f.package_root = pkg_root; |
| 276 | 282 | try loadManifest(f, pkg_root); |