Skip to content

Commit

Permalink
- fix symlink creation under @scope
Browse files Browse the repository at this point in the history
- fix use-after-free on package names
  • Loading branch information
alexlamsl committed Jan 11, 2023
1 parent 630a6b3 commit 95454b4
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 18 deletions.
66 changes: 51 additions & 15 deletions src/install/install.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1276,30 +1276,66 @@ const PackageInstall = struct {
// cache_dir_subpath in here is actually the full path to the symlink pointing to the linked package
const symlinked_path = this.cache_dir_subpath;

std.os.symlinkat(
std.fs.path.relative(this.allocator, "node_modules", symlinked_path[0..symlinked_path.len]) catch unreachable,
this.destination_dir.dir.fd,
dest_path[0..dest_path.len],
) catch |err| {
return Result{
const subdir = std.fs.path.dirname(dest_path);
var dest_dir = if (subdir) |dir| brk: {
break :brk this.destination_dir.dir.makeOpenPath(dir, .{}) catch |err| return Result{
.fail = .{
.err = err,
.step = .linking,
},
};
} else this.destination_dir.dir;
defer {
if (subdir != null) dest_dir.close();
}

var dest_full_path = dest_dir.realpathAlloc(this.allocator, ".") catch |err| return Result{
.fail = .{
.err = err,
.step = .linking,
},
};
defer this.allocator.free(dest_full_path);

if (isDanglingSymlink(symlinked_path)) {
return Result{
.fail = .{
.err = error.DanglingSymlink,
.step = .linking,
},
};
}
var to_path = std.fs.path.resolve(this.allocator, &[_]string{
FileSystem.instance.top_level_dir,
symlinked_path,
}) catch |err| return Result{
.fail = .{
.err = err,
.step = .linking,
},
};
defer this.allocator.free(to_path);

var target = std.fs.path.relative(
this.allocator,
dest_full_path,
to_path,
) catch |err| return Result{
.fail = .{
.err = err,
.step = .linking,
},
};
defer this.allocator.free(target);

std.os.symlinkat(target, dest_dir.fd, std.fs.path.basename(dest_path)) catch |err| return Result{
.fail = .{
.err = err,
.step = .linking,
},
};

if (isDanglingSymlink(symlinked_path)) return Result{
.fail = .{
.err = error.DanglingSymlink,
.step = .linking,
},
};

return Result{
.success = void{},
.success = {},
};
}

Expand Down
10 changes: 7 additions & 3 deletions src/install/lockfile.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2642,10 +2642,14 @@ pub const Package = extern struct {
if (json.asProperty(group.prop)) |dependencies_q| {
switch (dependencies_q.expr.data) {
.e_array => |arr| {
workspace_names = try allocator.alloc(string, arr.items.len);

var workspace_log = logger.Log.init(allocator);
defer log.deinit();

workspace_names = try allocator.alloc(string, arr.items.len);
var workspace_buf = try allocator.alloc(u8, 1024);
defer allocator.free(workspace_buf);

for (arr.slice()) |item, i| {
const path = item.asString(allocator) orelse return error.InvalidPackageJSON;

Expand All @@ -2655,7 +2659,6 @@ pub const Package = extern struct {
var workspace_file = try workspace_dir.openFile("package.json", .{ .mode = .read_only });
defer workspace_file.close();

var workspace_buf = try allocator.alloc(u8, 1024);
const workspace_read = try workspace_file.preadAll(workspace_buf, 0);
const workspace_source = logger.Source.initPathString(path, workspace_buf[0..workspace_read]);

Expand All @@ -2667,10 +2670,11 @@ pub const Package = extern struct {
if (!workspace_json.has_found_name) return error.InvalidPackageJSON;

const workspace_name = workspace_json.found_name;
workspace_names[i] = workspace_name;

string_builder.count(workspace_name);
string_builder.count(path);
string_builder.cap += bun.MAX_PATH_BYTES;
workspace_names[i] = try allocator.dupe(u8, workspace_name);
}
total_dependencies_count += @truncate(u32, arr.items.len);
},
Expand Down

0 comments on commit 95454b4

Please sign in to comment.