From: Michihiro NAKAJIMA Date: Fri, 1 Apr 2011 12:07:43 +0000 (-0400) Subject: Fix a replacement of Windows path separator in CP932 locale. X-Git-Tag: v3.0.0a~537 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e1635188d01b2b53fa2cce19474d1080b48037dd;p=thirdparty%2Flibarchive.git Fix a replacement of Windows path separator in CP932 locale. And update related comment. SVN-Revision: 3147 --- diff --git a/libarchive/archive_read_support_format_cab.c b/libarchive/archive_read_support_format_cab.c index 5628b9dbd..a80ad545d 100644 --- a/libarchive/archive_read_support_format_cab.c +++ b/libarchive/archive_read_support_format_cab.c @@ -560,24 +560,32 @@ cab_convert_path_separator(struct archive_read *a, struct cab *cab, struct archive_string *fn, unsigned char attr) { size_t i; + int mb; + /* Easy check if we have '\' in multi-byte string. */ + mb = 0; for (i = 0; i < archive_strlen(fn); i++) { - if (fn->s[i] == '\\') + if (fn->s[i] == '\\') { + if (mb) + break;/* This may be second byte of multi-byte character. */ fn->s[i] = '/'; - else if (fn->s[i] & 0x80) - /* Are there any multibyte characters in fn ? */ - break; + mb = 0; + } else if (fn->s[i] & 0x80) + mb = 1; + else + mb = 0; } if (i == archive_strlen(fn)) return; /* - * Try to replace a character in wide character. + * Try to replace a character '\' with '/' in wide character. */ - /* If a conversion to wide character failed, force a replacement. */ - if (!archive_wstring_append_from_mbs(&a->archive, &(cab->ws), - fn->s, fn->length)) { + /* If a conversion to wide character failed, force the replacement. */ + archive_string_empty(&(cab->ws)); + if (archive_wstring_append_from_mbs(&a->archive, &(cab->ws), + fn->s, fn->length) != 0) { for (i = 0; i < archive_strlen(fn); i++) { if (fn->s[i] == '\\') fn->s[i] = '/'; @@ -589,15 +597,14 @@ cab_convert_path_separator(struct archive_read *a, struct cab *cab, if (cab->ws.s[i] == L'\\') cab->ws.s[i] = L'/'; } - - /* - * Sanity check that we surely did not break a filename. - */ archive_string_empty(&(cab->mbs)); archive_string_append_from_unicode_to_mbs(&a->archive, &(cab->mbs), cab->ws.s, cab->ws.length); - /* If mbs length is different to fn, we broke the - * filename and we shouldn't use it. */ + /* + * Sanity check that we surely did not break a filename. + * If MBS length is different to fn, we broke the + * filename, and so we shouldn't use it. + */ if (archive_strlen(&(cab->mbs)) == archive_strlen(fn)) archive_string_copy(fn, &(cab->mbs)); } diff --git a/libarchive/archive_read_support_format_lha.c b/libarchive/archive_read_support_format_lha.c index b7567212f..ecf958474 100644 --- a/libarchive/archive_read_support_format_lha.c +++ b/libarchive/archive_read_support_format_lha.c @@ -711,33 +711,38 @@ archive_read_format_lha_read_header(struct archive_read *a, /* * Replace a DOS path separator '\' by a character '/'. * Some multi-byte character set have a character '\' in its second byte. - * Try to save a filename from breaking down as much as possible. - * Ideally, libarchive would have the ability to convert a character - * set for a filename in an archive. */ static void lha_replace_path_separator(struct archive_read *a, struct lha *lha, struct archive_string *fn) { size_t i; + int mb; + /* Easy check if we have '\' in multi-byte string. */ + mb = 0; for (i = 0; i < archive_strlen(fn); i++) { - if (fn->s[i] == '\\') + if (fn->s[i] == '\\') { + if (mb) + break;/* This may be second byte of multi-byte character. */ fn->s[i] = '/'; - else if (fn->s[i] & 0x80) - /* Are there any multibyte characters in fn ? */ - break; + mb = 0; + } else if (fn->s[i] & 0x80) + mb = 1; + else + mb = 0; } if (i == archive_strlen(fn)) return; /* - * Try to replace a character in wide character. + * Try to replace a character '\' with '/' in wide character. */ - /* If a conversion to wide character failed, force a replacement. */ - if (!archive_wstring_append_from_mbs(&a->archive, &(lha->ws), - fn->s, fn->length)) { + /* If a conversion to wide character failed, force the replacement. */ + archive_string_empty(&(lha->ws)); + if (archive_wstring_append_from_mbs(&a->archive, &(lha->ws), + fn->s, fn->length) != 0) { for (i = 0; i < archive_strlen(fn); i++) { if (fn->s[i] == '\\') fn->s[i] = '/'; @@ -749,15 +754,14 @@ lha_replace_path_separator(struct archive_read *a, struct lha *lha, if (lha->ws.s[i] == L'\\') lha->ws.s[i] = L'/'; } - - /* - * Sanity check that we surely did not break a filename. - */ archive_string_empty(&(lha->mbs)); archive_string_append_from_unicode_to_mbs(&a->archive, &(lha->mbs), lha->ws.s, lha->ws.length); - /* If mbs length is different to fn, we broke the - * filename and we shouldn't use it. */ + /* + * Sanity check that we surely did not break a filename. + * If MBS length is different to fn, we broke the + * filename, and so we shouldn't use it. + */ if (archive_strlen(&(lha->mbs)) == archive_strlen(fn)) archive_string_copy(fn, &(lha->mbs)); }