xref: /freebsd-src/contrib/libarchive/tar/test/test_option_P.c (revision 6c40282284d6eab20256914648cdec39acb2c52a)
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