From: Michihiro NAKAJIMA Date: Thu, 8 Jan 2009 01:40:05 +0000 (-0500) Subject: Replace a path separator to '/' in archive_write_disk.c, X-Git-Tag: v2.7.0~447 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d7a96c82a7c4e672429813aaed2a1849047ee9ca;p=thirdparty%2Flibarchive.git Replace a path separator to '/' in archive_write_disk.c, if the path separator of the running system is not '/'. Because of libarchive expect the path separator is '/' where program check the one. SVN-Revision: 403 --- diff --git a/libarchive/archive_windows.h b/libarchive/archive_windows.h index 95372c7b3..956d1dde3 100644 --- a/libarchive/archive_windows.h +++ b/libarchive/archive_windows.h @@ -250,6 +250,8 @@ struct _timeval64i32 { #define __timeval _timeval64i32 #endif +#define SYSTEM_PATH_CHAR '\\' + /* End of Win32 definitions. */ #ifdef __cplusplus diff --git a/libarchive/archive_write_disk.c b/libarchive/archive_write_disk.c index 6a96b0d4c..5aa50c191 100644 --- a/libarchive/archive_write_disk.c +++ b/libarchive/archive_write_disk.c @@ -1438,6 +1438,61 @@ check_symlinks(struct archive_write_disk *a) return (ARCHIVE_OK); } +#if defined(SYSTEM_PATH_CHAR) && SYSTEM_PATH_CHAR != '/' +/* Convert a path separator of the running system to '/' . + * We shouldn't check multi-byte character directly because some charsets + * are using a character of the path separator for a part of their charset. + */ +static void +cleanup_path_separator(struct archive_write_disk *a) +{ + wchar_t *ws, wpath_char; + size_t alen, i, l; + int replaced; + char path_char; + + if ((alen = strlen(a->name)) == 0) + return; + /* pre-check to reduce malloc and free */ + if (strchr(a->name, SYSTEM_PATH_CHAR) == NULL) + return; + path_char = SYSTEM_PATH_CHAR; + if (mbtowc(&wpath_char, &path_char, 1) != 1) + return; + ws = malloc((alen + 1)* sizeof(wchar_t)); + if (ws == NULL) + __archive_errx(1, "Out of memory"); + l = mbstowcs(ws, a->name, alen); + if (l == (size_t)-1) { + /* We cannot check path separator */ + free(ws); + return; + } + ws[l] = L'\0'; + replaced = 0; + for (i = 0; i < l; i++) { + if (ws[i] == wpath_char) { + ws[i] = L'/'; + replaced = 1; + } + } + if (replaced) { + char *p; + + p = malloc(alen + 1); + if (p == NULL) + __archive_errx(1, "Out of memory"); + l = wcstombs(p, ws, alen); + if (l == alen) + memcpy(a->name, p, l); + free(p); + } + free(ws); +} +#else +#define cleanup_path_separator(a) /* nothing */ +#endif + /* * Canonicalize the pathname. In particular, this strips duplicate * '/' characters, '.' elements, and trailing '/'. It also raises an @@ -1450,6 +1505,7 @@ cleanup_pathname(struct archive_write_disk *a) char *dest, *src; char separator = '\0'; + cleanup_path_separator(a); dest = src = a->name; if (*src == '\0') { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,