gpt.c was simply truncating the UTF-16 characters stored in the partition name field to 8 bits. This corrupted non ascii characters which later resulted in parted crashing in strlist.c trying to convert the now invalid multi byte characters to wchar.
gpt.c will now properly convert the UTF-16 to the current locale encoding. --- libparted/labels/gpt.c | 60 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 7 deletions(-) diff --git a/libparted/labels/gpt.c b/libparted/labels/gpt.c index 490de70..73109f4 100644 --- a/libparted/labels/gpt.c +++ b/libparted/labels/gpt.c @@ -39,6 +39,8 @@ #include <uuid/uuid.h> #include <stdbool.h> #include <errno.h> +#include <iconv.h> +#include <langinfo.h> #include "xalloc.h" #include "verify.h" @@ -192,7 +194,7 @@ struct __attribute__ ((packed)) _GuidPartitionEntry_t uint64_t StartingLBA; uint64_t EndingLBA; GuidPartitionEntryAttributes_t Attributes; - efi_char16_t PartitionName[72 / sizeof (efi_char16_t)]; + efi_char16_t PartitionName[36]; }; #define GPT_PMBR_LBA 0 @@ -276,7 +278,8 @@ typedef struct _GPTPartitionData { efi_guid_t type; efi_guid_t uuid; - char name[37]; + efi_char16_t name[37]; + char *translated_name; int lvm; int raid; int boot; @@ -785,10 +788,11 @@ _parse_part_entry (PedDisk *disk, GuidPartitionEntry_t *pte) gpt_part_data = part->disk_specific; gpt_part_data->type = pte->PartitionTypeGuid; gpt_part_data->uuid = pte->UniquePartitionGuid; - for (i = 0; i < 72 / sizeof (efi_char16_t); i++) + for (i = 0; i < 36; i++) gpt_part_data->name[i] = (efi_char16_t) PED_LE16_TO_CPU ((uint16_t) pte->PartitionName[i]); gpt_part_data->name[i] = 0; + gpt_part_data->translated_name = 0; gpt_part_data->lvm = gpt_part_data->raid = gpt_part_data->boot = gpt_part_data->hp_service @@ -1196,7 +1200,7 @@ _partition_generate_part_entry (PedPartition *part, GuidPartitionEntry_t *pte) if (gpt_part_data->legacy_boot) pte->Attributes.LegacyBIOSBootable = 1; - for (i = 0; i < 72 / sizeof (efi_char16_t); i++) + for (i = 0; i < 36; i++) pte->PartitionName[i] = (efi_char16_t) PED_CPU_TO_LE16 ((uint16_t) gpt_part_data->name[i]); } @@ -1371,6 +1375,8 @@ gpt_partition_duplicate (const PedPartition *part) goto error_free_part; *result_data = *part_data; + if (part_data->translated_name) + result_data->translated_name = strdup (part_data->translated_name); return result; error_free_part: @@ -1385,6 +1391,8 @@ gpt_partition_destroy (PedPartition *part) if (part->type == 0) { PED_ASSERT (part->disk_specific != NULL); + GPTPartitionData *gpt_part_data = part->disk_specific; + free (gpt_part_data->translated_name); free (part->disk_specific); } @@ -1776,15 +1784,53 @@ gpt_partition_set_name (PedPartition *part, const char *name) { GPTPartitionData *gpt_part_data = part->disk_specific; - strncpy (gpt_part_data->name, name, 36); - gpt_part_data->name[36] = 0; + free(gpt_part_data->translated_name); + gpt_part_data->translated_name = strdup(name); + iconv_t conv = iconv_open ("UTF-16", nl_langinfo (CODESET)); + if (conv == (iconv_t)-1) + goto err; + char *inbuff = gpt_part_data->translated_name; + char *outbuff = (char *)&gpt_part_data->name; + size_t inbuffsize = strlen (inbuff); + size_t outbuffsize = 72; + if (iconv (conv, &inbuff, &inbuffsize, &outbuff, &outbuffsize) == -1) + goto err; + iconv_close (conv); + return; + err: + ped_exception_throw (PED_EXCEPTION_WARNING, + PED_EXCEPTION_IGNORE, + _("Can not translate partition name")); + iconv_close (conv); } static const char * gpt_partition_get_name (const PedPartition *part) { GPTPartitionData *gpt_part_data = part->disk_specific; - return gpt_part_data->name; + if (gpt_part_data->translated_name == NULL) + { + char buffer[200]; + iconv_t conv = iconv_open (nl_langinfo (CODESET), "UTF-16"); + if (conv == (iconv_t)-1) + goto err; + char *inbuff = (char *)&gpt_part_data->name; + char *outbuff = buffer; + size_t inbuffsize = 72; + size_t outbuffsize = sizeof(buffer); + if (iconv (conv, &inbuff, &inbuffsize, &outbuff, &outbuffsize) == -1) + goto err; + iconv_close (conv); + *outbuff = 0; + gpt_part_data->translated_name = strdup (buffer); + return gpt_part_data->translated_name; + err: + ped_exception_throw (PED_EXCEPTION_WARNING, + PED_EXCEPTION_IGNORE, + _("Can not translate partition name")); + iconv_close (conv); + } + return gpt_part_data->translated_name; } static int -- 1.8.3.2