]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Fix a replacement of Windows path separator in CP932 locale.
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>
Fri, 1 Apr 2011 12:07:43 +0000 (08:07 -0400)
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>
Fri, 1 Apr 2011 12:07:43 +0000 (08:07 -0400)
And update related comment.

SVN-Revision: 3147

libarchive/archive_read_support_format_cab.c
libarchive/archive_read_support_format_lha.c

index 5628b9dbd87fdfd340f38f838fc6970e7a35670e..a80ad545d26338a684bd17f854b4034e13d5f686 100644 (file)
@@ -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));
 }
index b7567212f730869026b40829a35c961f7ba6a1a0..ecf9584743d7228625c97737635c7fc106606a15 100644 (file)
@@ -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));
 }