From: Michihiro NAKAJIMA Date: Sat, 26 Mar 2011 00:47:09 +0000 (-0400) Subject: Improve archive_wstring_append_from_mbs function; use mbsnrtowcs or X-Git-Tag: v3.0.0a~603 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=496b18769e2b47c9be888288bb7aa93000c8f90a;p=thirdparty%2Flibarchive.git Improve archive_wstring_append_from_mbs function; use mbsnrtowcs or mbsrtowcs for thread safe if available. SVN-Revision: 3075 --- diff --git a/CMakeLists.txt b/CMakeLists.txt index c7cb83de2..e2eef8dd6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -574,6 +574,8 @@ CHECK_FUNCTION_EXISTS_GLIBC(localtime_r HAVE_LOCALTIME_R) CHECK_FUNCTION_EXISTS_GLIBC(lstat HAVE_LSTAT) CHECK_FUNCTION_EXISTS_GLIBC(lutimes HAVE_LUTIMES) CHECK_FUNCTION_EXISTS_GLIBC(mbrtowc HAVE_MBRTOWC) +CHECK_FUNCTION_EXISTS_GLIBC(mbsnrtowcs HAVE_MBSNRTOWCS) +CHECK_FUNCTION_EXISTS_GLIBC(mbsrtowcs HAVE_MBSRTOWCS) CHECK_FUNCTION_EXISTS_GLIBC(memmove HAVE_MEMMOVE) CHECK_FUNCTION_EXISTS_GLIBC(mkdir HAVE_MKDIR) CHECK_FUNCTION_EXISTS_GLIBC(mkfifo HAVE_MKFIFO) diff --git a/build/cmake/config.h.in b/build/cmake/config.h.in index bc3cb0821..87263a7f5 100644 --- a/build/cmake/config.h.in +++ b/build/cmake/config.h.in @@ -619,6 +619,12 @@ typedef uint64_t uintmax_t; /* Define to 1 if you have the `mbrtowc' function. */ #cmakedefine HAVE_MBRTOWC 1 +/* Define to 1 if you have the `mbsnrtowcs' function. */ +#cmakedefine HAVE_MBSNRTOWCS 1 + +/* Define to 1 if you have the `mbsrtowcs' function. */ +#cmakedefine HAVE_MBSRTOWCS 1 + /* Define to 1 if you have the `memmove' function. */ #cmakedefine HAVE_MEMMOVE 1 diff --git a/configure.ac b/configure.ac index 1d43d173c..c628063d2 100644 --- a/configure.ac +++ b/configure.ac @@ -436,8 +436,9 @@ AC_CHECK_FUNCS([fchdir fchflags fchmod fchown fcntl fdopendir fork]) AC_CHECK_FUNCS([fstat fstatat fstatfs fstatvfs ftruncate futimens futimes]) AC_CHECK_FUNCS([geteuid getpid getgrgid_r getgrnam_r]) AC_CHECK_FUNCS([getpwnam_r getpwuid_r getvfsbyname gmtime_r]) -AC_CHECK_FUNCS([lchflags lchmod lchown link localtime_r lstat]) -AC_CHECK_FUNCS([lutimes mbrtowc memmove memset mkdir mkfifo mknod mkstemp]) +AC_CHECK_FUNCS([lchflags lchmod lchown link localtime_r lstat lutimes]) +AC_CHECK_FUNCS([mbrtowc mbsnrtowcs mbsrtowcs memmove memset]) +AC_CHECK_FUNCS([mkdir mkfifo mknod mkstemp]) AC_CHECK_FUNCS([nl_langinfo openat pipe poll readlink readlinkat]) AC_CHECK_FUNCS([select setenv setlocale sigaction statfs statvfs]) AC_CHECK_FUNCS([strchr strdup strerror strncpy_s strrchr symlink timegm]) diff --git a/libarchive/archive_string.c b/libarchive/archive_string.c index ee9332552..13137f170 100644 --- a/libarchive/archive_string.c +++ b/libarchive/archive_string.c @@ -327,11 +327,6 @@ archive_string_append_from_unicode_to_utf8(struct archive_string *as, const wcha return (return_val); } -/* - * UTF-8 ===> Unicode - * - */ - /* * Get the "current character set" name to use with iconv. * On FreeBSD, the empty character set name "" chooses @@ -472,14 +467,27 @@ archive_wstring_append_from_mbs(struct archive *a, * so this length estimate will always be big enough. */ size_t wcs_length = len; + const char *mbs = p; +#if HAVE_MBSRTOWCS || HAVE_MBSNRTOWCS + mbstate_t shift_state; + + memset(&shift_state, 0, sizeof(shift_state)); +#endif if (NULL == archive_wstring_ensure(dest, dest->length + wcs_length + 1)) __archive_errx(1, "No memory for archive_wstring_append_from_mbs()"); - r = mbstowcs(dest->s + dest->length, p, wcs_length); +#if HAVE_MBSNRTOWCS + r = mbsnrtowcs(dest->s + dest->length, &mbs, len, wcs_length, + &shift_state); +#elif HAVE_MBSRTOWCS + r = mbsrtowcs(dest->s + dest->length, &mbs, wcs_length, &shift_state); +#else + r = mbstowcs(dest->s + dest->length, mbs, wcs_length); +#endif if (r != (size_t)-1) { dest->length += r; - dest->s[dest->length] = 0; + dest->s[dest->length] = L'\0'; return (0); } return (-1);