Bug 707775: Ensure fz_is_directory() works with utf-8 on windows.
authorRobin Watts <[email protected]>
Wed, 12 Jun 2024 15:03:22 +0000 (16:03 +0100)
committerRobin Watts <[email protected]>
Tue, 23 Jul 2024 19:02:01 +0000 (20:02 +0100)
To do this, we've implemented fz_wchar_from_utf8 to mirror
fz_utf8_from_wchar.

include/mupdf/fitz/string-util.h
source/fitz/directory.c
source/fitz/string.c

index 76062e3fefbf444bd1da30e30ec7cd4c7861406b..4acc644f716c96c7cd0bf48ba39f864da166ed1e 100644 (file)
@@ -254,6 +254,11 @@ int fz_utflen(const char *s);
 */
 char *fz_utf8_from_wchar(fz_context *ctx, const wchar_t *s);
 
+/*
+       Convert a utf8 string into a new heap allocated wchar one.
+*/
+wchar_t *fz_wchar_from_utf8(fz_context *ctx, const char *path);
+
 
 /**
        Locale-independent decimal to binary conversion. On overflow
index b75c50550115525d62d9adb655e2884e881390a6..9088edd4830b17bdd37c8fb9f3f2a6aa0e0767e3 100644 (file)
@@ -89,12 +89,25 @@ static int has_dir_entry(fz_context *ctx, fz_archive *arch, const char *name)
 int
 fz_is_directory(fz_context *ctx, const char *path)
 {
+#ifdef _WIN32
+       wchar_t *wpath = fz_wchar_from_utf8(ctx, path);
+       struct stat info;
+       int ret;
+
+       ret = _wstat(wpath, &info);
+       fz_free(ctx, wpath);
+       if (ret < 0)
+               return 0;
+
+       return S_ISDIR(info.st_mode);
+#else
        struct stat info;
 
        if (stat(path, &info) < 0)
                return 0;
 
        return S_ISDIR(info.st_mode);
+#endif
 }
 
 static int
index 2745847d78f80f946e2a700ba5d81660896f9640..4a0de4fc48fcb003dca332d405bb9b5a723d2f6e 100644 (file)
@@ -971,3 +971,41 @@ fz_utf8_from_wchar(fz_context *ctx, const wchar_t *s)
 
        return d;
 }
+
+wchar_t *
+fz_wchar_from_utf8(fz_context *ctx, const char *path)
+{
+       size_t z = 0;
+       const char *p = path;
+       wchar_t *wpath, *w;
+
+       if (!path)
+               return NULL;
+
+       while (*p)
+       {
+               int c;
+               p += fz_chartorune(&c, p);
+               z++;
+               if (c >= 0x10000)
+                       z++;
+       }
+
+       w = wpath = fz_malloc(ctx, 2*(z+1));
+       while (*path)
+       {
+               int c;
+               path += fz_chartorune(&c, path);
+               if (c >= 0x10000)
+               {
+                       c -= 0x10000;
+                       *w++ = 0xd800 + (c>>10);
+                       *w++ = 0xdc00 + (c&1023);
+               }
+               else
+                       *w++ = c;
+       }
+       *w = 0;
+
+       return wpath;
+}