qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v2 08/13] vvfat: correctly create long names for non


From: Hervé Poussineau
Subject: [Qemu-devel] [PATCH v2 08/13] vvfat: correctly create long names for non-ASCII filenames
Date: Mon, 22 May 2017 23:12:00 +0200

Assume that input filename is encoded as UTF-8, so correctly create UTF-16 
encoding.

Signed-off-by: Hervé Poussineau <address@hidden>
---
 block/vvfat.c | 38 ++++++++++++++++++--------------------
 1 file changed, 18 insertions(+), 20 deletions(-)

diff --git a/block/vvfat.c b/block/vvfat.c
index d4664c531b..d34241da17 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -425,28 +425,19 @@ static void init_mbr(BDRVVVFATState *s, int cyls, int 
heads, int secs)
 
 /* direntry functions */
 
-/* dest is assumed to hold 258 bytes, and pads with 0xffff up to next multiple 
of 26 */
-static inline int short2long_name(char* dest,const char* src)
+static direntry_t *create_long_filename(BDRVVVFATState *s, const char 
*filename)
 {
-    int i;
-    int len;
-    for(i=0;i<129 && src[i];i++) {
-        dest[2*i]=src[i];
-        dest[2*i+1]=0;
+    int number_of_entries, i;
+    glong length;
+    direntry_t *entry;
+
+    gunichar2 *longname = g_utf8_to_utf16(filename, -1, NULL, &length, NULL);
+    if (!longname) {
+        fprintf(stderr, "vvfat: invalid UTF-8 name: %s\n", filename);
+        return NULL;
     }
-    len=2*i;
-    dest[2*i]=dest[2*i+1]=0;
-    for(i=2*i+2;(i%26);i++)
-        dest[i]=0xff;
-    return len;
-}
 
-static inline direntry_t* create_long_filename(BDRVVVFATState* s,const char* 
filename)
-{
-    char buffer[258];
-    int length=short2long_name(buffer,filename),
-        number_of_entries=(length+25)/26,i;
-    direntry_t* entry;
+    number_of_entries = (length * 2 + 25) / 26;
 
     for(i=0;i<number_of_entries;i++) {
         entry=array_get_next(&(s->directory));
@@ -461,8 +452,15 @@ static inline direntry_t* 
create_long_filename(BDRVVVFATState* s,const char* fil
         else if(offset<22) offset=14+offset-10;
         else offset=28+offset-22;
         entry=array_get(&(s->directory),s->directory.next-1-(i/26));
-        entry->name[offset]=buffer[i];
+        if (i >= 2 * length + 2) {
+            entry->name[offset] = 0xff;
+        } else if (i % 2 == 0) {
+            entry->name[offset] = longname[i / 2] & 0xff;
+        } else {
+            entry->name[offset] = longname[i / 2] >> 8;
+        }
     }
+    g_free(longname);
     return array_get(&(s->directory),s->directory.next-number_of_entries);
 }
 
-- 
2.11.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]