From a55cf07365ec2ff51749a77e09ae9edac79a99fe Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Tue, 27 Sep 2022 08:43:26 +0100 Subject: libarchive: alter handling of failure to create symlinks Unlike GNU tar upstream BusyBox tar treats all errors as fatal. Failure to create a symlink on Windows is very likely due to a lack of the required privilege. busybox-w32 therefore treats this case as a non-fatal error and, as far as possible, continues extracting files. However: - The inconsistency of this behaviour caused some confusion. - busybox-w32 tar didn't return an error status when a non-fatal error was encountered, unlike GNU tar. Change the implementation so extraction continues when symlink creation fails but the error report is deferred until all of the archive has been processed. Only one error is reported and it's treated as fatal. Saves 48-64 bytes. (GitHub issue #265) --- archival/libarchive/unsafe_symlink_target.c | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/archival/libarchive/unsafe_symlink_target.c b/archival/libarchive/unsafe_symlink_target.c index 8e4cd4380..d9100f30f 100644 --- a/archival/libarchive/unsafe_symlink_target.c +++ b/archival/libarchive/unsafe_symlink_target.c @@ -5,29 +5,31 @@ #include "libbb.h" #include "bb_archive.h" -/* symlink may not be available for WIN32, just issue a warning */ -#if ENABLE_PLATFORM_MINGW32 -# undef bb_perror_msg_and_die -# define bb_perror_msg_and_die(...) bb_perror_msg(__VA_ARGS__) -#endif - void FAST_FUNC create_or_remember_link(llist_t **link_placeholders, const char *target, const char *linkname, int hard_link) { +#if ENABLE_PLATFORM_MINGW32 + /* defer reporting error if symlink(2) fails on Windows */ + if (hard_link || target[0] == '/' || strstr(target, "..") || + symlink(target, linkname) != 0) { +#else if (hard_link || target[0] == '/' || strstr(target, "..")) { +#endif llist_add_to_end(link_placeholders, xasprintf("%c%s%c%s", hard_link, linkname, '\0', target) ); return; } +#if !ENABLE_PLATFORM_MINGW32 if (symlink(target, linkname) != 0) { /* shared message */ bb_perror_msg_and_die("can't create %slink '%s' to '%s'", "sym", linkname, target ); } +#endif } void FAST_FUNC create_links_from_list(llist_t *list) @@ -37,24 +39,11 @@ void FAST_FUNC create_links_from_list(llist_t *list) target = list->data + 1 + strlen(list->data + 1) + 1; if ((*list->data ? link : symlink) (target, list->data + 1)) { -#if !ENABLE_PLATFORM_MINGW32 /* shared message */ bb_error_msg_and_die("can't create %slink '%s' to '%s'", *list->data ? "hard" : "sym", list->data + 1, target ); -#else - if (!*list->data) - bb_error_msg("can't create %slink '%s' to '%s'", - "sym", - list->data + 1, target - ); - else - bb_error_msg_and_die("can't create %slink '%s' to '%s'", - "hard", - list->data + 1, target - ); -#endif } list = list->link; } -- cgit v1.2.3-55-g6feb