| ... | @@ -369,3 +369,60 @@ const Md5Writer = struct { | ... | @@ -369,3 +369,60 @@ const Md5Writer = struct { |
| 369 | return std.fmt.bytesToHex(s, .lower); | 369 | return std.fmt.bytesToHex(s, .lower); |
| 370 | } | 370 | } |
| 371 | }; | 371 | }; |
| | 372 | |
| | 373 | test "tar should not overwrite existing file" { |
| | 374 | // Starting from this folder structure: |
| | 375 | // $ tree root |
| | 376 | // root |
| | 377 | // ├── a |
| | 378 | // │   └── b |
| | 379 | // │   └── c |
| | 380 | // │   └── file.txt |
| | 381 | // └── d |
| | 382 | // └── b |
| | 383 | // └── c |
| | 384 | // └── file.txt |
| | 385 | // |
| | 386 | // Packed with command: |
| | 387 | // $ cd root; tar cf overwrite_file.tar * |
| | 388 | // Resulting tar has following structure: |
| | 389 | // $ tar tvf overwrite_file.tar |
| | 390 | // size path |
| | 391 | // 0 a/ |
| | 392 | // 0 a/b/ |
| | 393 | // 0 a/b/c/ |
| | 394 | // 2 a/b/c/file.txt |
| | 395 | // 0 d/ |
| | 396 | // 0 d/b/ |
| | 397 | // 0 d/b/c/ |
| | 398 | // 2 d/b/c/file.txt |
| | 399 | // |
| | 400 | // Note that there is no root folder in archive. |
| | 401 | // |
| | 402 | // With strip_components = 1 resulting unpacked folder was: |
| | 403 | // root |
| | 404 | // └── b |
| | 405 | // └── c |
| | 406 | // └── file.txt |
| | 407 | // |
| | 408 | // a/b/c/file.txt is overwritten with d/b/c/file.txt !!! |
| | 409 | // This ensures that file is not overwritten. |
| | 410 | // |
| | 411 | const data = @embedFile("testdata/overwrite_file.tar"); |
| | 412 | var fsb = std.io.fixedBufferStream(data); |
| | 413 | |
| | 414 | // Unpack with strip_components = 1 should fail |
| | 415 | var root = std.testing.tmpDir(.{}); |
| | 416 | defer root.cleanup(); |
| | 417 | try testing.expectError( |
| | 418 | error.PathAlreadyExists, |
| | 419 | tar.pipeToFileSystem(root.dir, fsb.reader(), .{ .mode_mode = .ignore, .strip_components = 1 }), |
| | 420 | ); |
| | 421 | |
| | 422 | // Unpack with strip_components = 0 should pass |
| | 423 | fsb.reset(); |
| | 424 | var root2 = std.testing.tmpDir(.{}); |
| | 425 | defer root2.cleanup(); |
| | 426 | try tar.pipeToFileSystem(root2.dir, fsb.reader(), .{ .mode_mode = .ignore, .strip_components = 0 }); |
| | 427 | } |
| | 428 | |