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