]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Use mbstowcs() at __la_win_permissive_name() instead of MultiByteToWideChar() with...
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>
Fri, 8 Apr 2011 07:45:20 +0000 (03:45 -0400)
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>
Fri, 8 Apr 2011 07:45:20 +0000 (03:45 -0400)
Reduce the effect of locale from the functions which used __la_win_permissive_name().

SVN-Revision: 3179

libarchive/archive_read_disk_windows.c
libarchive/archive_windows.c
libarchive/archive_windows.h

index 553ae44739722d90f3932dab24dc327b29dc8a5d..643c96a5a2aa16844bd7cf717846153b79d2a0fc 100644 (file)
@@ -1263,6 +1263,12 @@ tree_reopen(struct tree *t, const char *path, int restore_time)
            path, strlen(path)) != 0)
                goto failed;
        pathname = ws.s;
+       /* Get a full-path-name. */
+       p = __la_win_permissive_name_w(pathname);
+       if (p == NULL)
+               goto failed;
+       archive_wstrcpy(&(t->full_path), p);
+       free(p);
 
        /* Convert path separators from '\' to '/' */
        for (p = pathname; *p != L'\0'; ++p) {
@@ -1271,11 +1277,6 @@ tree_reopen(struct tree *t, const char *path, int restore_time)
        }
        base = pathname;
 
-       p = __la_win_permissive_name(path);
-       if (p == NULL)
-               goto failed;
-       archive_wstrcpy(&(t->full_path), p);
-       free(p);
        /* First item is set up a lot like a symlink traversal. */
        /* printf("Looking for wildcard in %s\n", path); */
        /* TODO: wildcard detection here screws up on \\?\c:\ UNC names */
index 159fc3cb8c132305a74878b0145fa5e9f0f62a2c..520a5c54bc1f69405d489c903fd4e1e53ee25242 100644 (file)
@@ -126,36 +126,41 @@ getino(struct ustat *ub)
 wchar_t *
 __la_win_permissive_name(const char *name)
 {
-       wchar_t *wn, *wnp;
-       wchar_t *ws, *wsp;
-       DWORD l, len, slen;
-       int unc;
+       wchar_t *wn;
+       wchar_t *ws;
+       size_t ll;
 
-       len = (DWORD)strlen(name);
-       wn = malloc((len + 1) * sizeof(wchar_t));
+       ll = strlen(name);
+       wn = malloc((ll + 1) * sizeof(wchar_t));
        if (wn == NULL)
                return (NULL);
-       l = MultiByteToWideChar(CP_ACP, 0,
-           name, (int)len, wn, (int)len);
-       if (l == 0) {
+       ll = mbstowcs(wn, name, ll);
+       if (ll == (size_t)-1) {
                free(wn);
                return (NULL);
        }
-       wn[l] = L'\0';
+       wn[ll] = L'\0';
+       ws = __la_win_permissive_name_w(wn);
+       free(wn);
+       return (ws);
+}
+
+wchar_t *
+__la_win_permissive_name_w(const wchar_t *wname)
+{
+       wchar_t *wn, *wnp;
+       wchar_t *ws, *wsp;
+       DWORD l, len, slen;
+       int unc;
 
        /* Get a full-pathname. */
-       l = GetFullPathNameW(wn, 0, NULL, NULL);
-       if (l == 0) {
-               free(wn);
+       l = GetFullPathNameW(wname, 0, NULL, NULL);
+       if (l == 0)
                return (NULL);
-       }
        wnp = malloc(l * sizeof(wchar_t));
-       if (wnp == NULL) {
-               free(wn);
+       if (wnp == NULL)
                return (NULL);
-       }
-       len = GetFullPathNameW(wn, l, wnp, NULL);
-       free(wn);
+       len = GetFullPathNameW(wname, l, wnp, NULL);
        wn = wnp;
 
        if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
@@ -1106,21 +1111,21 @@ __la_hash_Final(unsigned char *buf, size_t bufsize, Digest_CTX *ctx)
 int
 __archive_mktemp(const char *tmpdir)
 {
-       static const char num[] = {
-               '0', '1', '2', '3', '4', '5', '6', '7',
-               '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
-               'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
-               'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
-               'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
-               'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
-               'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
-               'u', 'v', 'w', 'x', 'y', 'z'
+       static const wchar_t num[] = {
+               L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7',
+               L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F',
+               L'G', L'H', L'I', L'J', L'K', L'L', L'M', L'N',
+               L'O', L'P', L'Q', L'R', L'S', L'T', L'U', L'V',
+               L'W', L'X', L'Y', L'Z', L'a', L'b', L'c', L'd',
+               L'e', L'f', L'g', L'h', L'i', L'j', L'k', L'l',
+               L'm', L'n', L'o', L'p', L'q', L'r', L's', L't',
+               L'u', L'v', L'w', L'x', L'y', L'z'
        };
        HCRYPTPROV hProv;
-       struct archive_string temp_name;
+       struct archive_wstring temp_name;
        wchar_t *ws;
        DWORD attr;
-       BYTE *xp, *ep;
+       wchar_t *xp, *ep;
        int fd;
 
        hProv = (HCRYPTPROV)NULL;
@@ -1131,35 +1136,36 @@ __archive_mktemp(const char *tmpdir)
        /* Get a temporary directory. */
        if (tmpdir == NULL) {
                size_t l;
-               char *tmp;
+               wchar_t *tmp;
 
-               l = GetTempPathA(0, NULL);
+               l = GetTempPathW(0, NULL);
                if (l == 0) {
                        la_dosmaperr(GetLastError());
                        goto exit_tmpfile;
                }
-               tmp = malloc(l);
+               tmp = malloc(l*sizeof(wchar_t));
                if (tmp == NULL) {
                        errno = ENOMEM;
                        goto exit_tmpfile;
                }
-               GetTempPathA(l, tmp);
-               archive_strcpy(&temp_name, tmp);
+               GetTempPathW(l, tmp);
+               archive_wstrcpy(&temp_name, tmp);
                free(tmp);
        } else {
-               archive_strcpy(&temp_name, tmpdir);
-               if (temp_name.s[temp_name.length-1] != '/')
-                       archive_strappend_char(&temp_name, '/');
+               archive_wstring_append_from_mbs(NULL, &temp_name, tmpdir,
+                   strlen(tmpdir));
+               if (temp_name.s[temp_name.length-1] != L'/')
+                       archive_wstrappend_wchar(&temp_name, L'/');
        }
 
        /* Check if temp_name is a directory. */
-       attr = GetFileAttributesA(temp_name.s);
+       attr = GetFileAttributesW(temp_name.s);
        if (attr == (DWORD)-1) {
                if (GetLastError() != ERROR_FILE_NOT_FOUND) {
                        la_dosmaperr(GetLastError());
                        goto exit_tmpfile;
                }
-               ws = __la_win_permissive_name(temp_name.s);
+               ws = __la_win_permissive_name_w(temp_name.s);
                if (ws == NULL) {
                        errno = EINVAL;
                        goto exit_tmpfile;
@@ -1178,10 +1184,10 @@ __archive_mktemp(const char *tmpdir)
        /*
         * Create a temporary file.
         */
-       archive_strcat(&temp_name, "libarchive_");
-       xp = ((BYTE *)temp_name.s) + archive_strlen(&temp_name);
-       archive_strcat(&temp_name, "XXXXXXXXXX");
-       ep = ((BYTE *)temp_name.s) + archive_strlen(&temp_name);
+       archive_wstrcat(&temp_name, L"libarchive_");
+       xp = temp_name.s + archive_strlen(&temp_name);
+       archive_wstrcat(&temp_name, L"XXXXXXXXXX");
+       ep = temp_name.s + archive_strlen(&temp_name);
 
        if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
                CRYPT_VERIFYCONTEXT)) {
@@ -1190,20 +1196,20 @@ __archive_mktemp(const char *tmpdir)
        }
 
        for (;;) {
-               BYTE *p;
+               wchar_t *p;
                HANDLE h;
 
                /* Generate a random file name through CryptGenRandom(). */
                p = xp;
-               if (!CryptGenRandom(hProv, ep - p, p)) {
+               if (!CryptGenRandom(hProv, (ep - p)*sizeof(wchar_t), (BYTE*)p)) {
                        la_dosmaperr(GetLastError());
                        goto exit_tmpfile;
                }
                for (; p < ep; p++)
-                       *p = num[*p % sizeof(num)];
+                       *p = num[((DWORD)*p) % (sizeof(num)/sizeof(num[0]))];
 
                free(ws);
-               ws = __la_win_permissive_name(temp_name.s);
+               ws = __la_win_permissive_name_w(temp_name.s);
                if (ws == NULL) {
                        errno = EINVAL;
                        goto exit_tmpfile;
@@ -1238,7 +1244,7 @@ exit_tmpfile:
        if (hProv != (HCRYPTPROV)NULL)
                CryptReleaseContext(hProv, 0);
        free(ws);
-       archive_string_free(&temp_name);
+       archive_wstring_free(&temp_name);
        return (fd);
 }
 
index 9681b9737c2dbe1ad2c69c7792c38585a7aff100..6e97d3c45044d3db69c256f06692c48abb60d8fa 100644 (file)
@@ -283,5 +283,6 @@ extern ssize_t       __la_write(int fd, const void *buf, size_t nbytes);
 #define WEXITSTATUS(sts)       (sts & 0x0FF)
 
 extern wchar_t *__la_win_permissive_name(const char *name);
+extern wchar_t *__la_win_permissive_name_w(const wchar_t *wname);
 
 #endif /* LIBARCHIVE_ARCHIVE_WINDOWS_H_INCLUDED */