From e4068fb87cb9cc2f557f65081f505a805fdcdcda Mon Sep 17 00:00:00 2001 From: ljdarj Date: Fri, 11 Oct 2024 08:18:55 +0200 Subject: [PATCH] Change to Windows absolute symlinks. (#2362) Change to read absolute symlinks as verbatim paths instead of NT paths: as far as I can see, libarchive can deal with verbatim paths while it can't with NT ones. Fixes #2274. --- libarchive/archive_read_disk_windows.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/libarchive/archive_read_disk_windows.c b/libarchive/archive_read_disk_windows.c index feb870b11..cb59b5160 100644 --- a/libarchive/archive_read_disk_windows.c +++ b/libarchive/archive_read_disk_windows.c @@ -49,6 +49,8 @@ /* Old SDKs do not provide IO_REPARSE_TAG_SYMLINK */ #define IO_REPARSE_TAG_SYMLINK 0xA000000CL #endif +/* To deal with absolute symlink isuues */ +#define START_ABSOLUTE_SYMLINK_REPARSE L"\\??\\" /*- * This is a new directory-walking system that addresses a number @@ -375,7 +377,7 @@ la_linkname_from_handle(HANDLE h, wchar_t **linkname, int *linktype) return (-1); } - tbuf = malloc(len + 1 * sizeof(wchar_t)); + tbuf = malloc(len + sizeof(wchar_t)); if (tbuf == NULL) { free(indata); return (-1); @@ -386,18 +388,21 @@ la_linkname_from_handle(HANDLE h, wchar_t **linkname, int *linktype) free(indata); tbuf[len / sizeof(wchar_t)] = L'\0'; + if (wcsncmp(tbuf, START_ABSOLUTE_SYMLINK_REPARSE, 4) == 0) { + /* Absolute symlink, so we'll change the NT path into a verbatim one */ + tbuf[1] = L'\\'; + } else { + /* Relative symlink, so we can translate backslashes to slashes */ + wchar_t *temp = tbuf; + do { + if (*temp == L'\\') + *temp = L'/'; + temp++; + } while(*temp != L'\0'); + } *linkname = tbuf; - /* - * Translate backslashes to slashes for libarchive internal use - */ - while(*tbuf != L'\0') { - if (*tbuf == L'\\') - *tbuf = L'/'; - tbuf++; - } - if ((st.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) *linktype = AE_SYMLINK_TYPE_FILE; else -- 2.47.3