1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2024 Mostyn Bramley-Moore <mostyn@antipode.se> 5 */ 6 7 #include "test.h" 8 9 #include <stdlib.h> 10 #include <string.h> 11 12 #if defined(_WIN32) && !defined(__CYGWIN__) 13 #define UNLINK _unlink 14 #else 15 #define UNLINK unlink 16 #endif 17 18 DEFINE_TEST(test_extract_tar_absolute_paths) 19 { 20 int r; 21 22 // Create an absolute path for a test file inside testworkdir. 23 char *entry_suffix = "/tar-noabs"; 24 size_t entry_suffix_length = strlen(entry_suffix); 25 size_t testworkdir_length = strlen(testworkdir); 26 size_t temp_absolute_file_name_length = testworkdir_length + entry_suffix_length; 27 char *temp_absolute_file_name = calloc(1, temp_absolute_file_name_length + 1); // +1 for null character. 28 assertEqualInt(snprintf(temp_absolute_file_name, temp_absolute_file_name_length + 1, "%s%s", testworkdir, entry_suffix), 29 temp_absolute_file_name_length); 30 31 #if defined(_WIN32) && !defined(__CYGWIN__) 32 // I'm unsure how to specify paths with spaces for the test invocation on windows. 33 // Adding quotes doesn't seem to work. We should find a way to escape these paths, 34 // but for now let's fail in a place that's obviously related to the test setup if 35 // testworkdir contains spaces. 36 for (char *p = temp_absolute_file_name; *p != '\0'; p++) 37 { 38 assert(*p != ' '); 39 if (*p == ' ') break; 40 } 41 #endif 42 43 // Create the file. 44 const char *sample_data = "test file from test_extract_tar_absolute_paths"; 45 assertMakeFile(temp_absolute_file_name, 0644, sample_data); 46 47 // Create an archive with the test file, using an absolute path. 48 #if defined(_WIN32) && !defined(__CYGWIN__) 49 r = systemf("%s --absolute-paths -cf test.tar %s", testprog, temp_absolute_file_name); 50 #else 51 r = systemf("%s --absolute-paths -cf test.tar \"%s\"", testprog, temp_absolute_file_name); 52 #endif 53 assertEqualInt(r, 0); 54 55 UNLINK(temp_absolute_file_name); 56 57 // Extracting the archive without -P / --absolute-paths should strip leading drive letter or slash 58 r = systemf("%s -xf test.tar 2>test.err", testprog); 59 assertEqualInt(r, 0); 60 assertFileNotExists(temp_absolute_file_name); 61 62 // Check that the mangled path exists. 63 #if defined(_WIN32) && !defined(__CYGWIN__) 64 assertFileExists(temp_absolute_file_name + 3); // Skip the drive letter, colon and slash. 65 UNLINK(temp_absolute_file_name + 3); 66 #else 67 assertFileExists(temp_absolute_file_name + 1); // Skip the slash. 68 UNLINK(temp_absolute_file_name + 1); 69 #endif 70 71 // Extracting the archive with -P / --absolute-paths should create the file. 72 r = systemf("%s --absolute-paths -xf test.tar", testprog); 73 assertEqualInt(r, 0); 74 assertFileExists(temp_absolute_file_name); 75 76 // Check that the mangled path wasn't created. 77 #if defined(_WIN32) && !defined(__CYGWIN__) 78 assertFileNotExists(temp_absolute_file_name + 3); // Skip the drive letter, colon and slash. 79 #else 80 assertFileNotExists(temp_absolute_file_name + 1); // Skip the slash. 81 #endif 82 } 83