* include/grub/charset.h (GRUB_MAX_UTF8_PER_UTF16): New const.
* grub-core/fs/hfsplus.c (grub_hfsplus_catkey_internal): Change to UTF-16-BE. All users updated. (grub_hfsplus_cmp_catkey): Fix unicode handling. (grub_hfsplus_iterate_dir): Likewise. (grub_hfsplus_label): Likewise.
This commit is contained in:
parent
48d6e45653
commit
1bc8f60db7
3 changed files with 43 additions and 61 deletions
|
@ -1,3 +1,12 @@
|
|||
2011-12-12 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* include/grub/charset.h (GRUB_MAX_UTF8_PER_UTF16): New const.
|
||||
* grub-core/fs/hfsplus.c (grub_hfsplus_catkey_internal): Change to
|
||||
UTF-16-BE. All users updated.
|
||||
(grub_hfsplus_cmp_catkey): Fix unicode handling.
|
||||
(grub_hfsplus_iterate_dir): Likewise.
|
||||
(grub_hfsplus_label): Likewise.
|
||||
|
||||
2011-12-12 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/disk/ahci.c (grub_ahci_pciinit): Fix compat condition.
|
||||
|
|
|
@ -181,7 +181,8 @@ enum grub_hfsplus_filetype
|
|||
struct grub_hfsplus_catkey_internal
|
||||
{
|
||||
grub_uint32_t parent;
|
||||
const char *name;
|
||||
const grub_uint16_t *name;
|
||||
grub_size_t namelen;
|
||||
};
|
||||
|
||||
/* Internal representation of an extent overflow key. */
|
||||
|
@ -519,8 +520,6 @@ grub_hfsplus_cmp_catkey (struct grub_hfsplus_key *keya,
|
|||
{
|
||||
struct grub_hfsplus_catkey *catkey_a = &keya->catkey;
|
||||
struct grub_hfsplus_catkey_internal *catkey_b = &keyb->catkey;
|
||||
char *filename;
|
||||
int i;
|
||||
int diff;
|
||||
|
||||
/* Safe unsigned comparison */
|
||||
|
@ -530,26 +529,13 @@ grub_hfsplus_cmp_catkey (struct grub_hfsplus_key *keya,
|
|||
if (aparent < catkey_b->parent)
|
||||
return -1;
|
||||
|
||||
/* Change the filename in keya so the endianness is correct. */
|
||||
for (i = 0; i < grub_be_to_cpu16 (catkey_a->namelen); i++)
|
||||
catkey_a->name[i] = grub_be_to_cpu16 (catkey_a->name[i]);
|
||||
diff = grub_memcmp (catkey_a->name, catkey_b->name,
|
||||
grub_min (grub_be_to_cpu16 (catkey_a->namelen),
|
||||
catkey_b->namelen)
|
||||
* sizeof (catkey_a->name[0]));
|
||||
if (diff == 0)
|
||||
diff = grub_be_to_cpu16 (catkey_a->namelen) - catkey_b->namelen;
|
||||
|
||||
filename = grub_malloc (grub_be_to_cpu16 (catkey_a->namelen) + 1);
|
||||
|
||||
if (! grub_utf16_to_utf8 ((grub_uint8_t *) filename, catkey_a->name,
|
||||
grub_be_to_cpu16 (catkey_a->namelen)))
|
||||
return -1; /* XXX: This error never occurs, but in case it happens
|
||||
just skip this entry. */
|
||||
|
||||
diff = grub_strncmp (filename, catkey_b->name,
|
||||
grub_be_to_cpu16 (catkey_a->namelen));
|
||||
|
||||
grub_free (filename);
|
||||
|
||||
/* The endianness was changed to host format, change it back to
|
||||
whatever it was. */
|
||||
for (i = 0; i < grub_be_to_cpu16 (catkey_a->namelen); i++)
|
||||
catkey_a->name[i] = grub_cpu_to_be16 (catkey_a->name[i]);
|
||||
return diff;
|
||||
}
|
||||
|
||||
|
@ -792,6 +778,11 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir,
|
|||
if (type == GRUB_FSHELP_UNKNOWN)
|
||||
return 0;
|
||||
|
||||
filename = grub_malloc (grub_be_to_cpu16 (catkey->namelen)
|
||||
* GRUB_MAX_UTF8_PER_UTF16 + 1);
|
||||
if (! filename)
|
||||
return 0;
|
||||
|
||||
/* Make sure the byte order of the UTF16 string is correct. */
|
||||
for (i = 0; i < grub_be_to_cpu16 (catkey->namelen); i++)
|
||||
{
|
||||
|
@ -802,18 +793,8 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir,
|
|||
return 0;
|
||||
}
|
||||
|
||||
filename = grub_malloc (grub_be_to_cpu16 (catkey->namelen) + 1);
|
||||
if (! filename)
|
||||
return 0;
|
||||
|
||||
if (! grub_utf16_to_utf8 ((grub_uint8_t *) filename, catkey->name,
|
||||
grub_be_to_cpu16 (catkey->namelen)))
|
||||
{
|
||||
grub_free (filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
filename[grub_be_to_cpu16 (catkey->namelen)] = '\0';
|
||||
*grub_utf16_to_utf8 ((grub_uint8_t *) filename, catkey->name,
|
||||
grub_be_to_cpu16 (catkey->namelen)) = '\0';
|
||||
|
||||
/* Restore the byte order to what it was previously. */
|
||||
for (i = 0; i < grub_be_to_cpu16 (catkey->namelen); i++)
|
||||
|
@ -823,22 +804,18 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir,
|
|||
if (! dir->data->case_sensitive)
|
||||
type |= GRUB_FSHELP_CASE_INSENSITIVE;
|
||||
|
||||
/* Only accept valid nodes. */
|
||||
if (grub_strlen (filename) == grub_be_to_cpu16 (catkey->namelen))
|
||||
{
|
||||
/* A valid node is found; setup the node and call the
|
||||
callback function. */
|
||||
node = grub_malloc (sizeof (*node));
|
||||
node->data = dir->data;
|
||||
/* A valid node is found; setup the node and call the
|
||||
callback function. */
|
||||
node = grub_malloc (sizeof (*node));
|
||||
node->data = dir->data;
|
||||
|
||||
grub_memcpy (node->extents, fileinfo->data.extents,
|
||||
sizeof (node->extents));
|
||||
node->mtime = grub_be_to_cpu32 (fileinfo->mtime) - 2082844800;
|
||||
node->size = grub_be_to_cpu64 (fileinfo->data.size);
|
||||
node->fileid = grub_be_to_cpu32 (fileinfo->fileid);
|
||||
grub_memcpy (node->extents, fileinfo->data.extents,
|
||||
sizeof (node->extents));
|
||||
node->mtime = grub_be_to_cpu32 (fileinfo->mtime) - 2082844800;
|
||||
node->size = grub_be_to_cpu64 (fileinfo->data.size);
|
||||
node->fileid = grub_be_to_cpu32 (fileinfo->fileid);
|
||||
|
||||
ret = hook (filename, type, node);
|
||||
}
|
||||
ret = hook (filename, type, node);
|
||||
|
||||
grub_free (filename);
|
||||
|
||||
|
@ -851,7 +828,8 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir,
|
|||
|
||||
/* Create a key that points to the first entry in the directory. */
|
||||
intern.catkey.parent = dir->fileid;
|
||||
intern.catkey.name = "";
|
||||
intern.catkey.name = 0;
|
||||
intern.catkey.namelen = 0;
|
||||
|
||||
/* First lookup the first entry. */
|
||||
if (grub_hfsplus_btree_search (&dir->data->catalog_tree, &intern,
|
||||
|
@ -999,7 +977,8 @@ grub_hfsplus_label (grub_device_t device, char **label)
|
|||
|
||||
/* Create a key that points to the label. */
|
||||
intern.catkey.parent = 1;
|
||||
intern.catkey.name = "";
|
||||
intern.catkey.name = 0;
|
||||
intern.catkey.namelen = 0;
|
||||
|
||||
/* First lookup the first entry. */
|
||||
if (grub_hfsplus_btree_search (&data->catalog_tree, &intern,
|
||||
|
@ -1022,20 +1001,12 @@ grub_hfsplus_label (grub_device_t device, char **label)
|
|||
return 0;
|
||||
}
|
||||
|
||||
*label = grub_malloc (label_len + 1);
|
||||
*label = grub_malloc (label_len * GRUB_MAX_UTF8_PER_UTF16 + 1);
|
||||
if (! *label)
|
||||
return grub_errno;
|
||||
|
||||
if (! grub_utf16_to_utf8 ((grub_uint8_t *) (*label), catkey->name,
|
||||
label_len))
|
||||
{
|
||||
grub_free (node);
|
||||
grub_free (*label);
|
||||
grub_free (data);
|
||||
*label = 0;
|
||||
return grub_errno;
|
||||
}
|
||||
(*label)[label_len] = '\0';
|
||||
*grub_utf16_to_utf8 ((grub_uint8_t *) (*label), catkey->name,
|
||||
label_len) = '\0';
|
||||
|
||||
grub_free (node);
|
||||
grub_free (data);
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
#define GRUB_UINT8_5_TRAILINGBITS 0x1f
|
||||
#define GRUB_UINT8_6_TRAILINGBITS 0x3f
|
||||
|
||||
#define GRUB_MAX_UTF8_PER_UTF16 4
|
||||
|
||||
#define GRUB_UCS2_LIMIT 0x10000
|
||||
#define GRUB_UTF16_UPPER_SURROGATE(code) \
|
||||
(0xD800 + ((((code) - GRUB_UCS2_LIMIT) >> 12) & 0xfff))
|
||||
|
|
Loading…
Reference in a new issue