From 189593857c736841fb79cfabbcb280f690c3ab81 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 19 Apr 2010 02:41:48 +0200 Subject: [PATCH] * fs/udf.c (grub_udf_iterate_dir): Decode the Unicode filenames. --- ChangeLog | 4 ++++ fs/udf.c | 33 ++++++++++++++++++++++++++++----- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index c9c398603..ee2cf4079 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-04-19 Vladimir Serbinenko + + * fs/udf.c (grub_udf_iterate_dir): Decode the Unicode filenames. + 2010-04-18 Vladimir Serbinenko * boot/sparc64/ieee1275/boot.S: Various size-reducing changes. diff --git a/fs/udf.c b/fs/udf.c index cecb6eb78..725468f54 100644 --- a/fs/udf.c +++ b/fs/udf.c @@ -25,6 +25,7 @@ #include #include #include +#include #define GRUB_UDF_MAX_PDS 2 #define GRUB_UDF_MAX_PMS 6 @@ -745,19 +746,41 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir, else { enum grub_fshelp_filetype type; - char filename[dirent.file_ident_length + 1]; + 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; type = ((dirent.characteristics & GRUB_UDF_FID_CHAR_DIRECTORY) ? (GRUB_FSHELP_DIR) : (GRUB_FSHELP_REG)); if ((grub_udf_read_file (dir, 0, offset, - dirent.file_ident_length, filename)) + dirent.file_ident_length, + (char *) raw)) != dirent.file_ident_length) return 0; - filename[dirent.file_ident_length] = 0; - if (hook (&filename[1], type, child)) - return 1; + if (raw[0] == 8) + { + 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)) + return 1; + } } /* Align to dword boundary. */