Home | History | Annotate | Line # | Download | only in test
      1 /*-
      2  * SPDX-License-Identifier: BSD-2-Clause
      3  *
      4  * Copyright (c) 2024 Mostyn Bramley-Moore <mostyn (at) 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