From 0c625fed12b1bbbe85a1c08846a2a24b8746a745 Mon Sep 17 00:00:00 2001 From: Upendra Date: Thu, 1 Mar 2018 17:15:48 +0900 Subject: [PATCH] AOSP: blkid: Correct the label name for exfat 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 Bug: 74184636 Test: manual Change-Id: Ib16204c75c2cdf675d480e9c66f484bb3c51108e From AOSP commit: 25715073b170970469126426196c9e5084613c37 --- lib/blkid/probe.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/lib/blkid/probe.c b/lib/blkid/probe.c index 283ee0a..2e92344 100644 --- a/lib/blkid/probe.c +++ b/lib/blkid/probe.c @@ -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); } -- 1.8.3.1