diff options
Diffstat (limited to 'libarchive/archive_string.c')
-rw-r--r-- | libarchive/archive_string.c | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/libarchive/archive_string.c b/libarchive/archive_string.c index 979a418b6779..399299ea631f 100644 --- a/libarchive/archive_string.c +++ b/libarchive/archive_string.c @@ -75,6 +75,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_string.c 201095 2009-12-28 02:33 #define wmemmove(a,b,i) (wchar_t *)memmove((a), (b), (i) * sizeof(wchar_t)) #endif +#undef max +#define max(a, b) ((a)>(b)?(a):(b)) + struct archive_string_conv { struct archive_string_conv *next; char *from_charset; @@ -591,7 +594,7 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest, * No single byte will be more than one wide character, * so this length estimate will always be big enough. */ - size_t wcs_length = len; + // size_t wcs_length = len; size_t mbs_length = len; const char *mbs = p; wchar_t *wcs; @@ -600,7 +603,11 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest, memset(&shift_state, 0, sizeof(shift_state)); #endif - if (NULL == archive_wstring_ensure(dest, dest->length + wcs_length + 1)) + /* + * As we decided to have wcs_length == mbs_length == len + * we can use len here instead of wcs_length + */ + if (NULL == archive_wstring_ensure(dest, dest->length + len + 1)) return (-1); wcs = dest->s + dest->length; /* @@ -609,6 +616,12 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest, * multi bytes. */ while (*mbs && mbs_length > 0) { + /* + * The buffer we allocated is always big enough. + * Keep this code path in a comment if we decide to choose + * smaller wcs_length in the future + */ +/* if (wcs_length == 0) { dest->length = wcs - dest->s; dest->s[dest->length] = L'\0'; @@ -618,24 +631,20 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest, return (-1); wcs = dest->s + dest->length; } +*/ #if HAVE_MBRTOWC - r = mbrtowc(wcs, mbs, wcs_length, &shift_state); + r = mbrtowc(wcs, mbs, mbs_length, &shift_state); #else - r = mbtowc(wcs, mbs, wcs_length); + r = mbtowc(wcs, mbs, mbs_length); #endif if (r == (size_t)-1 || r == (size_t)-2) { ret_val = -1; - if (errno == EILSEQ) { - ++mbs; - --mbs_length; - continue; - } else - break; + break; } if (r == 0 || r > mbs_length) break; wcs++; - wcs_length--; + // wcs_length--; mbs += r; mbs_length -= r; } @@ -798,7 +807,8 @@ archive_string_append_from_wcs(struct archive_string *as, as->s[as->length] = '\0'; /* Re-allocate buffer for MBS. */ if (archive_string_ensure(as, - as->length + len * 2 + 1) == NULL) + as->length + max(len * 2, + (size_t)MB_CUR_MAX) + 1) == NULL) return (-1); p = as->s + as->length; end = as->s + as->buffer_length - MB_CUR_MAX -1; @@ -3440,7 +3450,8 @@ strncat_from_utf8_libarchive2(struct archive_string *as, as->length = p - as->s; /* Re-allocate buffer for MBS. */ if (archive_string_ensure(as, - as->length + len * 2 + 1) == NULL) + as->length + max(len * 2, + (size_t)MB_CUR_MAX) + 1) == NULL) return (-1); p = as->s + as->length; end = as->s + as->buffer_length - MB_CUR_MAX -1; |