From 67707657a4c380a8b1d0d0ca1e1042d3ff26253f Mon Sep 17 00:00:00 2001 From: Juan RP Date: Fri, 27 Dec 2019 23:05:07 +0100 Subject: [PATCH] xbps-create: always sanitize gathered symlinks. Added a new test case. Close #199 --- bin/xbps-create/main.c | 26 +++++++++++++++++--------- tests/xbps/xbps-create/basic_test.sh | 28 ++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/bin/xbps-create/main.c b/bin/xbps-create/main.c index 2bd0adc1..b8669bd2 100644 --- a/bin/xbps-create/main.c +++ b/bin/xbps-create/main.c @@ -388,8 +388,9 @@ ftw_cb(const char *fpath, const struct stat *sb, const struct dirent *dir UNUSED * which might be provided in another package. * So let's use the same target. */ - xe->target = strdup(buf); - xbps_dictionary_set_cstring(fileinfo, "target", buf); + xe->target = xbps_sanitize_path(buf); + assert(xe->target); + xbps_dictionary_set_cstring(fileinfo, "target", xe->target); } else { /* * Sanitize destdir just in case. @@ -397,10 +398,14 @@ ftw_cb(const char *fpath, const struct stat *sb, const struct dirent *dir UNUSED if ((p2 = realpath(destdir, NULL)) == NULL) die("failed to sanitize destdir %s: %s", destdir, strerror(errno)); - xe->target = strdup(p+strlen(p2)); - xbps_dictionary_set_cstring(fileinfo, "target", p+strlen(p2)); - free(p2); + + p2 = strdup(p+strlen(p2)); + assert(p2); + xe->target = xbps_sanitize_path(p2); + assert(xe->target); + xbps_dictionary_set_cstring(fileinfo, "target", xe->target); free(p); + free(p2); } } else if (buf[0] != '/') { /* relative path */ @@ -408,14 +413,17 @@ ftw_cb(const char *fpath, const struct stat *sb, const struct dirent *dir UNUSED assert(p); dname = dirname(p); assert(dname); - xe->target = xbps_xasprintf("%s/%s", dname, buf); p2 = xbps_xasprintf("%s/%s", dname, buf); - xbps_dictionary_set_cstring(fileinfo, "target", p2); + assert(p2); + xe->target = xbps_sanitize_path(p2); + assert(xe->target); + xbps_dictionary_set_cstring(fileinfo, "target", xe->target); free(p2); free(p); } else { - xe->target = strdup(buf); - xbps_dictionary_set_cstring(fileinfo, "target", buf); + xe->target = xbps_sanitize_path(buf); + assert(xe->target); + xbps_dictionary_set_cstring(fileinfo, "target", xe->target); } assert(xe->target); assert(xbps_dictionary_get(fileinfo, "target")); diff --git a/tests/xbps/xbps-create/basic_test.sh b/tests/xbps/xbps-create/basic_test.sh index 2ed09c21..5e9a996f 100644 --- a/tests/xbps/xbps-create/basic_test.sh +++ b/tests/xbps/xbps-create/basic_test.sh @@ -58,6 +58,33 @@ symlink_relative_target_body() { atf_check_equal $rv 0 } +atf_test_case symlink_sanitize + +symlink_sanitize_head() { + atf_set "descr" "xbps-create(1): symlinks must be properly sanitized" +} + +symlink_sanitize_body() { + mkdir -p repo pkg_A/usr/bin + ln -s //usr/bin pkg_A/bin + + cd repo + xbps-create -A noarch -n foo-1.0_1 -s "foo pkg" ../pkg_A + atf_check_equal $? 0 + cd .. + xbps-rindex -d -a repo/*.xbps + atf_check_equal $? 0 + result="$(xbps-query -r root --repository=repo -f foo|tr -d '\n')" + expected="/bin -> /usr/bin" + rv=0 + if [ "$result" != "$expected" ]; then + echo "result: $result" + echo "expected: $expected" + rv=1 + fi + atf_check_equal $rv 0 +} + atf_test_case symlink_relative_target_cwd symlink_relative_target_cwd_head() { @@ -156,6 +183,7 @@ atf_init_test_cases() { atf_add_test_case hardlinks_size atf_add_test_case symlink_relative_target atf_add_test_case symlink_relative_target_cwd + atf_add_test_case symlink_sanitize atf_add_test_case restore_mtime atf_add_test_case reproducible_pkg atf_add_test_case reject_fifo_file