mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 22:35:24 +00:00
std.tar don't overwrite existing file
Fail with error if file already exists. File is not silently overwritten but an error is raised. Fixes: #18089
This commit is contained in:
parent
6fddc9cd3d
commit
b84301c8e5
@ -544,12 +544,12 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi
|
||||
const file_name = stripComponents(file.name, options.strip_components);
|
||||
if (file_name.len == 0) return error.BadFileName;
|
||||
|
||||
const fs_file = dir.createFile(file_name, .{}) catch |err| switch (err) {
|
||||
const fs_file = dir.createFile(file_name, .{ .exclusive = true }) catch |err| switch (err) {
|
||||
error.FileNotFound => again: {
|
||||
const code = code: {
|
||||
if (std.fs.path.dirname(file_name)) |dir_name| {
|
||||
dir.makePath(dir_name) catch |code| break :code code;
|
||||
break :again dir.createFile(file_name, .{}) catch |code| {
|
||||
break :again dir.createFile(file_name, .{ .exclusive = true }) catch |code| {
|
||||
break :code code;
|
||||
};
|
||||
}
|
||||
|
||||
@ -369,3 +369,60 @@ const Md5Writer = struct {
|
||||
return std.fmt.bytesToHex(s, .lower);
|
||||
}
|
||||
};
|
||||
|
||||
test "tar should not overwrite existing file" {
|
||||
// Starting from this folder structure:
|
||||
// $ tree root
|
||||
// root
|
||||
// ├── a
|
||||
// │ └── b
|
||||
// │ └── c
|
||||
// │ └── file.txt
|
||||
// └── d
|
||||
// └── b
|
||||
// └── c
|
||||
// └── file.txt
|
||||
//
|
||||
// Packed with command:
|
||||
// $ cd root; tar cf overwrite_file.tar *
|
||||
// Resulting tar has following structure:
|
||||
// $ tar tvf overwrite_file.tar
|
||||
// size path
|
||||
// 0 a/
|
||||
// 0 a/b/
|
||||
// 0 a/b/c/
|
||||
// 2 a/b/c/file.txt
|
||||
// 0 d/
|
||||
// 0 d/b/
|
||||
// 0 d/b/c/
|
||||
// 2 d/b/c/file.txt
|
||||
//
|
||||
// Note that there is no root folder in archive.
|
||||
//
|
||||
// With strip_components = 1 resulting unpacked folder was:
|
||||
// root
|
||||
// └── b
|
||||
// └── c
|
||||
// └── file.txt
|
||||
//
|
||||
// a/b/c/file.txt is overwritten with d/b/c/file.txt !!!
|
||||
// This ensures that file is not overwritten.
|
||||
//
|
||||
const data = @embedFile("testdata/overwrite_file.tar");
|
||||
var fsb = std.io.fixedBufferStream(data);
|
||||
|
||||
// Unpack with strip_components = 1 should fail
|
||||
var root = std.testing.tmpDir(.{});
|
||||
defer root.cleanup();
|
||||
try testing.expectError(
|
||||
error.PathAlreadyExists,
|
||||
tar.pipeToFileSystem(root.dir, fsb.reader(), .{ .mode_mode = .ignore, .strip_components = 1 }),
|
||||
);
|
||||
|
||||
// Unpack with strip_components = 0 should pass
|
||||
fsb.reset();
|
||||
var root2 = std.testing.tmpDir(.{});
|
||||
defer root2.cleanup();
|
||||
try tar.pipeToFileSystem(root2.dir, fsb.reader(), .{ .mode_mode = .ignore, .strip_components = 0 });
|
||||
}
|
||||
|
||||
|
||||
BIN
lib/std/tar/testdata/overwrite_file.tar
vendored
Normal file
BIN
lib/std/tar/testdata/overwrite_file.tar
vendored
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user