handle UTF16 UDF label
This commit is contained in:
parent
f22c12e852
commit
f8e2e451e6
1 changed files with 45 additions and 23 deletions
|
@ -789,6 +789,43 @@ fail:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
read_string (grub_uint8_t *raw, grub_size_t sz)
|
||||||
|
{
|
||||||
|
grub_uint16_t *utf16;
|
||||||
|
char *ret;
|
||||||
|
grub_size_t utf16len = 0;
|
||||||
|
|
||||||
|
if (raw[0] != 8 && raw[0] != 16)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (raw[0] == 8)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
utf16len = sz - 1;
|
||||||
|
utf16 = grub_malloc (utf16len * sizeof (utf16[0]));
|
||||||
|
if (!utf16)
|
||||||
|
return NULL;
|
||||||
|
for (i = 0; i < utf16len; i++)
|
||||||
|
utf16[i] = raw[i + 1];
|
||||||
|
}
|
||||||
|
if (raw[0] == 16)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
utf16len = (sz - 1) / 2;
|
||||||
|
utf16 = grub_malloc (utf16len * sizeof (utf16[0]));
|
||||||
|
if (!utf16)
|
||||||
|
return NULL;
|
||||||
|
for (i = 0; i < utf16len; i++)
|
||||||
|
utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2];
|
||||||
|
}
|
||||||
|
ret = grub_malloc (utf16len * 3 + 1);
|
||||||
|
if (ret)
|
||||||
|
*grub_utf16_to_utf8 ((grub_uint8_t *) ret, utf16, utf16len) = '\0';
|
||||||
|
grub_free (utf16);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
grub_udf_iterate_dir (grub_fshelp_node_t dir,
|
grub_udf_iterate_dir (grub_fshelp_node_t dir,
|
||||||
int NESTED_FUNC_ATTR
|
int NESTED_FUNC_ATTR
|
||||||
|
@ -842,10 +879,8 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
enum grub_fshelp_filetype type;
|
enum grub_fshelp_filetype type;
|
||||||
|
char *filename;
|
||||||
grub_uint8_t raw[dirent.file_ident_length];
|
grub_uint8_t raw[dirent.file_ident_length];
|
||||||
grub_uint16_t utf16[dirent.file_ident_length - 1];
|
|
||||||
grub_uint8_t filename[dirent.file_ident_length * 2];
|
|
||||||
grub_size_t utf16len = 0;
|
|
||||||
|
|
||||||
type = ((dirent.characteristics & GRUB_UDF_FID_CHAR_DIRECTORY) ?
|
type = ((dirent.characteristics & GRUB_UDF_FID_CHAR_DIRECTORY) ?
|
||||||
(GRUB_FSHELP_DIR) : (GRUB_FSHELP_REG));
|
(GRUB_FSHELP_DIR) : (GRUB_FSHELP_REG));
|
||||||
|
@ -856,27 +891,14 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir,
|
||||||
!= dirent.file_ident_length)
|
!= dirent.file_ident_length)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (raw[0] == 8)
|
filename = read_string (raw, dirent.file_ident_length);
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
utf16len = dirent.file_ident_length - 1;
|
|
||||||
for (i = 0; i < utf16len; i++)
|
|
||||||
utf16[i] = raw[i + 1];
|
|
||||||
}
|
|
||||||
if (raw[0] == 16)
|
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
utf16len = (dirent.file_ident_length - 1) / 2;
|
|
||||||
for (i = 0; i < utf16len; i++)
|
|
||||||
utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2];
|
|
||||||
}
|
|
||||||
if (raw[0] == 8 || raw[0] == 16)
|
|
||||||
{
|
|
||||||
*grub_utf16_to_utf8 (filename, utf16, utf16len) = '\0';
|
|
||||||
|
|
||||||
if (hook ((char *) filename, type, child))
|
if (filename && hook (filename, type, child))
|
||||||
return 1;
|
{
|
||||||
|
grub_free (filename);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
grub_free (filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1033,7 +1055,7 @@ grub_udf_label (grub_device_t device, char **label)
|
||||||
|
|
||||||
if (data)
|
if (data)
|
||||||
{
|
{
|
||||||
*label = grub_strdup ((char *) &data->lvd.ident[1]);
|
*label = read_string (data->lvd.ident, sizeof (data->lvd.ident));
|
||||||
grub_free (data);
|
grub_free (data);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in a new issue