]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
We should use mbrtowc/mbtowc at archive_wstring_append_from_mbs instead of
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>
Sat, 26 Mar 2011 03:21:44 +0000 (23:21 -0400)
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>
Sat, 26 Mar 2011 03:21:44 +0000 (23:21 -0400)
mbsrtowcs/mbstowcs because we cannot check the MBS limit specified by
a caller with a parameter 'len', and it is possible that mbsrtowcs/mbstowcs
convert extra MBS when strlen(MBS) > 'len'.

SVN-Revision: 3077

CMakeLists.txt
build/cmake/config.h.in
configure.ac
libarchive/archive_string.c

index e2eef8dd6e7719ca9f09ab4cfbe14226822895af..0fcd5235fb014fe3ea91177683e6844717b43b0c 100644 (file)
@@ -575,7 +575,6 @@ 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)
index 87263a7f5fd22e4735881a39fc459c42c759eecb..07364a1ce64927581e161824d0cb9b507d97be26 100644 (file)
@@ -622,9 +622,6 @@ typedef uint64_t uintmax_t;
 /* 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
 
index c628063d2f44105887c50804267bc29e3c3eb9de..b679a99e8d241ae02b336024cfb403054ed2938f 100644 (file)
@@ -437,7 +437,7 @@ 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 lutimes])
-AC_CHECK_FUNCS([mbrtowc mbsnrtowcs mbsrtowcs memmove memset])
+AC_CHECK_FUNCS([mbrtowc mbsnrtowcs 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])
index 3a0a397ded343bdf93526dba3f347744a8a849a6..d0c859dc240c3525ac55ca4bfc2caef5a56c7d8d 100644 (file)
@@ -469,8 +469,10 @@ archive_wstring_append_from_mbs(struct archive *a,
         * so this length estimate will always be big enough.
         */
        size_t wcs_length = len;
+       size_t mbs_length = len;
        const char *mbs = p;
-#if HAVE_MBSRTOWCS || HAVE_MBSNRTOWCS
+       wchar_t *wcs;
+#if HAVE_MBRTOWC || HAVE_MBSNRTOWCS
        mbstate_t shift_state;
 
        memset(&shift_state, 0, sizeof(shift_state));
@@ -478,21 +480,42 @@ archive_wstring_append_from_mbs(struct archive *a,
        if (NULL == archive_wstring_ensure(dest, dest->length + wcs_length + 1))
                __archive_errx(1,
                    "No memory for archive_wstring_append_from_mbs()");
-
+       wcs = dest->s + dest->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
+       r = mbsnrtowcs(wcs, &mbs, mbs_length, wcs_length, &shift_state);
        if (r != (size_t)-1) {
                dest->length += r;
                dest->s[dest->length] = L'\0';
                return (0);
        }
        return (-1);
+#else /* HAVE_MBSNRTOWCS */
+       /*
+        * We cannot use mbsrtowcs/mbstowcs here because those may convert
+        * extra MBS when strlen(p) > len and one wide character consis of
+        * multi bytes.
+        */
+       while (wcs_length > 0 && *mbs && mbs_length > 0) {
+#if HAVE_MBRTOWC
+               r = mbrtowc(wcs, mbs, wcs_length, &shift_state);
+#else
+               r = mbtowc(wcs, mbs, wcs_length);
+#endif
+               if (r == (size_t)-1 || r == (size_t)-2) {
+                       dest->s[dest->length] = L'\0';
+                       return (-1);
+               }
+               if (r == 0 || r > mbs_length)
+                       break;
+               wcs++;
+               wcs_length--;
+               mbs += r;
+               mbs_length -= r;
+       }
+       dest->length = wcs - dest->s;
+       dest->s[dest->length] = L'\0';
+       return (0);
+#endif /* HAVE_MBSNRTOWCS */
 }
 
 #endif