diff options
Diffstat (limited to 'lib/blkid/probe.c')
-rw-r--r-- | lib/blkid/probe.c | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/lib/blkid/probe.c b/lib/blkid/probe.c index 865d9aa3..0293b903 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) @@ -1482,7 +1513,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); } |