]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Add absolute path test for bsdtar (#2370)
authorMostyn Bramley-Moore <mostyn@antipode.se>
Mon, 7 Oct 2024 03:35:28 +0000 (05:35 +0200)
committerGitHub <noreply@github.com>
Mon, 7 Oct 2024 03:35:28 +0000 (20:35 -0700)
Check that extracting archive entries with absolute paths uses mangled
relative paths unless -P / --absolute-paths is specified.

Makefile.am
tar/test/CMakeLists.txt
tar/test/test_option_P.c [new file with mode: 0644]

index 64af9afd9b89b67463ab89e801f216ed5d486bad..53f47bb0ce95ce028525491d6335711a20110ba3 100644 (file)
@@ -1117,6 +1117,7 @@ bsdtar_test_SOURCES= \
        tar/test/test_option_H_upper.c \
        tar/test/test_option_L_upper.c \
        tar/test/test_option_O_upper.c \
+       tar/test/test_option_P.c \
        tar/test/test_option_T_upper.c \
        tar/test/test_option_U_upper.c \
        tar/test/test_option_X_upper.c \
index 7808a8d1f2ba095f0793090cdbcd0c9d9c4e271c..09ad6801547c7d3cf2c7ee4251b1195721bb6359 100644 (file)
@@ -32,6 +32,7 @@ IF(ENABLE_TAR AND ENABLE_TEST)
     test_option_H_upper.c
     test_option_L_upper.c
     test_option_O_upper.c
+    test_option_P.c
     test_option_T_upper.c
     test_option_U_upper.c
     test_option_X_upper.c
diff --git a/tar/test/test_option_P.c b/tar/test/test_option_P.c
new file mode 100644 (file)
index 0000000..e63da3e
--- /dev/null
@@ -0,0 +1,82 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2024 Mostyn Bramley-Moore <mostyn@antipode.se>
+ */
+
+#include "test.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#define UNLINK _unlink
+#else
+#define UNLINK unlink
+#endif
+
+DEFINE_TEST(test_extract_tar_absolute_paths)
+{
+       int r;
+
+       // Create an absolute path for a test file inside testworkdir.
+       char *entry_suffix = "/tar-noabs";
+       size_t entry_suffix_length = strlen(entry_suffix);
+       size_t testworkdir_length = strlen(testworkdir);
+       size_t temp_absolute_file_name_length = testworkdir_length + entry_suffix_length;
+       char *temp_absolute_file_name = calloc(1, temp_absolute_file_name_length + 1); // +1 for null character.
+       assertEqualInt(snprintf(temp_absolute_file_name, temp_absolute_file_name_length + 1, "%s%s", testworkdir, entry_suffix),
+               temp_absolute_file_name_length);
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+       // I'm unsure how to specify paths with spaces for the test invocation on windows.
+       // Adding quotes doesn't seem to work. We should find a way to escape these paths,
+       // but for now let's fail in a place that's obviously related to the test setup if
+       // testworkdir contains spaces.
+       for (char *p = temp_absolute_file_name; *p != '\0'; p++)
+       {
+               assert(*p != ' ');
+               if (*p == ' ') break;
+       }
+#endif
+
+       // Create the file.
+       const char *sample_data = "test file from test_extract_tar_absolute_paths";
+       assertMakeFile(temp_absolute_file_name, 0644, sample_data);
+
+       // Create an archive with the test file, using an absolute path.
+#if defined(_WIN32) && !defined(__CYGWIN__)
+       r = systemf("%s --absolute-paths -cf test.tar %s", testprog, temp_absolute_file_name);
+#else
+       r = systemf("%s --absolute-paths -cf test.tar \"%s\"", testprog, temp_absolute_file_name);
+#endif
+       assertEqualInt(r, 0);
+
+       UNLINK(temp_absolute_file_name);
+
+       // Extracting the archive without -P / --absolute-paths should strip leading drive letter or slash
+       r = systemf("%s -xf test.tar", testprog);
+       assertEqualInt(r, 0);
+       assertFileNotExists(temp_absolute_file_name);
+
+       // Check that the mangled path exists.
+#if defined(_WIN32) && !defined(__CYGWIN__)
+       assertFileExists(temp_absolute_file_name + 3); // Skip the drive letter, colon and slash.
+       UNLINK(temp_absolute_file_name + 3);
+#else
+       assertFileExists(temp_absolute_file_name + 1); // Skip the slash.
+       UNLINK(temp_absolute_file_name + 1);
+#endif
+
+       // Extracting the archive with -P / --absolute-paths should create the file.
+       r = systemf("%s --absolute-paths -xf test.tar", testprog);
+       assertEqualInt(r, 0);
+       assertFileExists(temp_absolute_file_name);
+
+       // Check that the mangled path wasn't created.
+#if defined(_WIN32) && !defined(__CYGWIN__)
+       assertFileNotExists(temp_absolute_file_name + 3); // Skip the drive letter, colon and slash.
+#else
+       assertFileNotExists(temp_absolute_file_name + 1); // Skip the slash.
+#endif
+}