Skip to content

Commit 3cc60d5

Browse files
committed
Harden cmux theme override writes
1 parent a0dfa8c commit 3cc60d5

1 file changed

Lines changed: 42 additions & 17 deletions

File tree

src/cli/list_themes.zig

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -330,9 +330,25 @@ fn readOptionalFile(alloc: std.mem.Allocator, path: []const u8) !?[]u8 {
330330
fn writeAbsoluteFile(path: []const u8, contents: []const u8) !void {
331331
if (std.fs.path.dirname(path)) |dir| {
332332
try std.fs.cwd().makePath(dir);
333+
var dir_handle = try std.fs.openDirAbsolute(dir, .{});
334+
defer dir_handle.close();
335+
336+
var buf: [1024]u8 = undefined;
337+
var atomic_file = try dir_handle.atomicFile(std.fs.path.basename(path), .{
338+
.mode = 0o600,
339+
.write_buffer = &buf,
340+
});
341+
defer atomic_file.deinit();
342+
343+
try atomic_file.file_writer.interface.writeAll(contents);
344+
try atomic_file.finish();
345+
return;
333346
}
334347

335-
var file = try std.fs.createFileAbsolute(path, .{ .truncate = true });
348+
var file = try std.fs.createFileAbsolute(path, .{
349+
.truncate = true,
350+
.mode = 0o600,
351+
});
336352
defer file.close();
337353
try file.writeAll(contents);
338354
}
@@ -341,25 +357,34 @@ fn removeManagedThemeOverride(
341357
alloc: std.mem.Allocator,
342358
contents: []const u8,
343359
) ![]u8 {
344-
const start = std.mem.indexOf(u8, contents, cmux_block_start) orelse
345-
return try alloc.dupe(u8, contents);
346-
const end_marker = std.mem.indexOfPos(u8, contents, start, cmux_block_end) orelse
347-
return try alloc.dupe(u8, contents);
348-
349-
var remove_start = start;
350-
if (remove_start > 0 and contents[remove_start - 1] == '\n') {
351-
remove_start -= 1;
352-
}
360+
var result: std.ArrayList(u8) = .empty;
361+
errdefer result.deinit(alloc);
362+
363+
var cursor: usize = 0;
364+
while (true) {
365+
const start = std.mem.indexOfPos(u8, contents, cursor, cmux_block_start) orelse {
366+
try result.appendSlice(alloc, contents[cursor..]);
367+
break;
368+
};
369+
const end_marker = std.mem.indexOfPos(u8, contents, start, cmux_block_end) orelse {
370+
try result.appendSlice(alloc, contents[cursor..]);
371+
break;
372+
};
373+
374+
var remove_start = start;
375+
if (remove_start > cursor and contents[remove_start - 1] == '\n') {
376+
remove_start -= 1;
377+
}
353378

354-
var remove_end = end_marker + cmux_block_end.len;
355-
if (remove_end < contents.len and contents[remove_end] == '\n') {
356-
remove_end += 1;
379+
var remove_end = end_marker + cmux_block_end.len;
380+
if (remove_end < contents.len and contents[remove_end] == '\n') {
381+
remove_end += 1;
382+
}
383+
384+
try result.appendSlice(alloc, contents[cursor..remove_start]);
385+
cursor = remove_end;
357386
}
358387

359-
var result: std.ArrayList(u8) = .empty;
360-
errdefer result.deinit(alloc);
361-
try result.appendSlice(alloc, contents[0..remove_start]);
362-
try result.appendSlice(alloc, contents[remove_end..]);
363388
return try result.toOwnedSlice(alloc);
364389
}
365390

0 commit comments

Comments
 (0)