Whamcloud - gitweb
AOSP: blkid: Correct the label name for exfat
authorUpendra <upendra.baveja@sony.com>
Thu, 1 Mar 2018 08:15:48 +0000 (17:15 +0900)
committerTheodore Ts'o <tytso@mit.edu>
Sat, 18 Aug 2018 19:59:40 +0000 (15:59 -0400)
Volume label name is 16 bit unicode string according to spec.
Currently blkid labels the device without converting it to
utf-8 chars due to which incorrect label is displayed.

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Bug: 74184636
Test: manual
Change-Id: Ib16204c75c2cdf675d480e9c66f484bb3c51108e
From AOSP commit: 25715073b170970469126426196c9e5084613c37

lib/blkid/probe.c

index 283ee0a..2e92344 100644 (file)
@@ -1160,6 +1160,37 @@ static void unicode_16be_to_utf8(unsigned char *str, int out_len,
        str[j] = '\0';
 }
 
+static void unicode_16le_to_utf8(unsigned char *str, int out_len,
+                                const unsigned char *buf, int in_len)
+{
+       int i, j;
+       unsigned int c;
+
+       for (i = j = 0; i + 2 <= in_len; i += 2) {
+               c = (buf[i+1] << 8) | buf[i];
+               if (c == 0) {
+                       str[j] = '\0';
+                       break;
+               } else if (c < 0x80) {
+                       if (j+1 >= out_len)
+                               break;
+                       str[j++] = (unsigned char) c;
+               } else if (c < 0x800) {
+                       if (j+2 >= out_len)
+                               break;
+                       str[j++] = (unsigned char) (0xc0 | (c >> 6));
+                       str[j++] = (unsigned char) (0x80 | (c & 0x3f));
+               } else {
+                       if (j+3 >= out_len)
+                               break;
+                       str[j++] = (unsigned char) (0xe0 | (c >> 12));
+                       str[j++] = (unsigned char) (0x80 | ((c >> 6) & 0x3f));
+                       str[j++] = (unsigned char) (0x80 | (c & 0x3f));
+               }
+       }
+       str[j] = '\0';
+}
+
 static int probe_hfs(struct blkid_probe *probe __BLKID_ATTR((unused)),
                         struct blkid_magic *id __BLKID_ATTR((unused)),
                         unsigned char *buf)
@@ -1487,7 +1518,9 @@ static int probe_exfat(struct blkid_probe *probe, struct blkid_magic *id,
 
     label = find_exfat_entry_label(probe, sb);
     if (label) {
-        blkid_set_tag(probe->dev, "LABEL", label->name, label->length);
+        char utf8_label[128];
+        unicode_16le_to_utf8(utf8_label, sizeof(utf8_label), label->name, label->length * 2);
+        blkid_set_tag(probe->dev, "LABEL", utf8_label, 0);
     } else {
         blkid_set_tag(probe->dev, "LABEL", "disk", 4);
     }