From: Tim Kientzle Date: Sat, 7 Feb 2015 07:00:30 +0000 (-0800) Subject: Issue 398: Overlapping memcpy X-Git-Tag: v3.1.900a~142 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b6ba5603;p=thirdparty%2Flibarchive.git Issue 398: Overlapping memcpy Some of the pathname edits parse a part of the pathname in the entry, then try to set the pathname from that part. This leads the text routines to memcpy() from within the string buffer. Avoid this by simply using memmove() for low-level string append operations. --- diff --git a/CMakeLists.txt b/CMakeLists.txt index a9d2531e2..6e8ea374d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1219,6 +1219,7 @@ CHECK_FUNCTION_EXISTS(strftime HAVE_STRFTIME) CHECK_FUNCTION_EXISTS(vprintf HAVE_VPRINTF) CHECK_FUNCTION_EXISTS(wmemcmp HAVE_WMEMCMP) CHECK_FUNCTION_EXISTS(wmemcpy HAVE_WMEMCPY) +CHECK_FUNCTION_EXISTS(wmemmove HAVE_WMEMMOVE) CMAKE_POP_CHECK_STATE() # Restore the state of the variables diff --git a/configure.ac b/configure.ac index 09e505c39..739cb0209 100644 --- a/configure.ac +++ b/configure.ac @@ -585,7 +585,7 @@ AC_CHECK_FUNCS([readpassphrase]) AC_CHECK_FUNCS([select setenv setlocale sigaction statfs statvfs]) AC_CHECK_FUNCS([strchr strdup strerror strncpy_s strrchr symlink timegm]) AC_CHECK_FUNCS([tzset unsetenv utime utimensat utimes vfork]) -AC_CHECK_FUNCS([wcrtomb wcscmp wcscpy wcslen wctomb wmemcmp wmemcpy]) +AC_CHECK_FUNCS([wcrtomb wcscmp wcscpy wcslen wctomb wmemcmp wmemcpy wmemmove]) AC_CHECK_FUNCS([_ctime64_s _fseeki64]) AC_CHECK_FUNCS([_get_timezone _localtime64_s _mkgmtime64]) # detects cygwin-1.7, as opposed to older versions diff --git a/libarchive/archive_string.c b/libarchive/archive_string.c index eebd7642b..5bd81a038 100644 --- a/libarchive/archive_string.c +++ b/libarchive/archive_string.c @@ -71,6 +71,10 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_string.c 201095 2009-12-28 02:33 #define wmemcpy(a,b,i) (wchar_t *)memcpy((a), (b), (i) * sizeof(wchar_t)) #endif +#if !defined(HAVE_WMEMMOVE) && !defined(wmemmove) +#define wmemmove(a,b,i) (wchar_t *)memmove((a), (b), (i) * sizeof(wchar_t)) +#endif + struct archive_string_conv { struct archive_string_conv *next; char *from_charset; @@ -203,7 +207,7 @@ archive_string_append(struct archive_string *as, const char *p, size_t s) { if (archive_string_ensure(as, as->length + s + 1) == NULL) return (NULL); - memcpy(as->s + as->length, p, s); + memmove(as->s + as->length, p, s); as->length += s; as->s[as->length] = 0; return (as); @@ -214,7 +218,7 @@ archive_wstring_append(struct archive_wstring *as, const wchar_t *p, size_t s) { if (archive_wstring_ensure(as, as->length + s + 1) == NULL) return (NULL); - wmemcpy(as->s + as->length, p, s); + wmemmove(as->s + as->length, p, s); as->length += s; as->s[as->length] = 0; return (as);