* docs/grub.texi (Filesystems): Mention SFS as Latin1 filesystem.

* grub-core/fs/sfs.c (grub_sfs_mount): Fix a memory leak while on it.
	(grub_sfs_iterate_dir): Convert Latin1 to UTF8. Stylistic and
	performance fixes while on it.
	(grub_sfs_close): Fix memory leak while on it.
	(grub_sfs_label): Convert Latin1 to UTF-8.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2011-12-25 22:39:56 +01:00
parent f50e11653e
commit ec000eaca9
3 changed files with 52 additions and 16 deletions

View file

@ -1,3 +1,12 @@
2011-12-25 Vladimir Serbinenko <phcoder@gmail.com>
* docs/grub.texi (Filesystems): Mention SFS as Latin1 filesystem.
* grub-core/fs/sfs.c (grub_sfs_mount): Fix a memory leak while on it.
(grub_sfs_iterate_dir): Convert Latin1 to UTF8. Stylistic and
performance fixes while on it.
(grub_sfs_close): Fix memory leak while on it.
(grub_sfs_label): Convert Latin1 to UTF-8.
2011-12-25 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/fs/hfs.c (grub_hfs_dir): Cap keylen to actually available

View file

@ -3940,14 +3940,14 @@ ISO9660 (plain and RockRidge), nilfs2, UFS1, UFS2 and ZFS are assumed
to be UTF-8. This might be false on systems configured with legacy charset
but as long as the charset used is superset of ASCII you should be able to
access ASCII-named files. And it's recommended to configure your system to use
UTF-8 to access the filesystem, convmv may help with migration. AFFS and HFS
never use unicode and GRUB assumes them to be in Latin1 and MacRoman
respectively. GRUB handles filesystem case-insensitivity however no attempt
is performed at case conversion of international characters so e.g. a file
named lowercase greek alpha is treated as different from the one named
as uppercase alpha. The filesystems in questions are NTFS (except POSIX
namespace), HFS+ (by default), FAT, exFAT
and ZFS (configurable on per-subvolume basis by property ``casesensitivity'',
UTF-8 to access the filesystem, convmv may help with migration. AFFS, SFS
and HFS never use unicode and GRUB assumes them to be in Latin1, Latin1
and MacRoman respectively. GRUB handles filesystem case-insensitivity however
no attempt is performed at case conversion of international characters
so e.g. a file named lowercase greek alpha is treated as different from
the one named as uppercase alpha. The filesystems in questions are
NTFS (except POSIX namespace), HFS+ (by default), FAT, exFAT and
ZFS (configurable on per-subvolume basis by property ``casesensitivity'',
default sensitive). On ZFS subvolumes marked as case insensitive files
containing lowercase international characters are inaccessible.
Also like all supported filesystems except HFS+ and ZFS (configurable on

View file

@ -25,6 +25,7 @@
#include <grub/dl.h>
#include <grub/types.h>
#include <grub/fshelp.h>
#include <grub/charset.h>
GRUB_MOD_LICENSE ("GPLv3+");
@ -303,6 +304,7 @@ grub_sfs_mount (grub_disk_t disk)
data->disk = disk;
data->label = grub_strdup ((char *) (rootobjc->objects[0].filename));
grub_free (rootobjc_data);
return data;
fail:
@ -357,24 +359,39 @@ grub_sfs_iterate_dir (grub_fshelp_node_t dir,
unsigned int next = dir->block;
int pos;
auto int NESTED_FUNC_ATTR grub_sfs_create_node (const char *name, int block,
auto int NESTED_FUNC_ATTR grub_sfs_create_node (const char *name,
int block,
int size, int type,
grub_uint32_t mtime);
int NESTED_FUNC_ATTR grub_sfs_create_node (const char *name, int block,
int NESTED_FUNC_ATTR grub_sfs_create_node (const char *name,
int block,
int size, int type,
grub_uint32_t mtime)
{
grub_size_t len = grub_strlen (name);
grub_uint8_t *name_u8;
int ret;
node = grub_malloc (sizeof (*node));
if (!node)
return 1;
name_u8 = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1);
if (!name_u8)
{
grub_free (node);
return 1;
}
node->data = data;
node->size = size;
node->block = block;
node->mtime = mtime;
return hook (name, type, node);
*grub_latin1_to_utf8 (name_u8, (const grub_uint8_t *) name, len) = '\0';
ret = hook ((char *) name_u8, type, node);
grub_free (name_u8);
return ret;
}
objc_data = grub_malloc (data->blocksize);
@ -398,7 +415,7 @@ grub_sfs_iterate_dir (grub_fshelp_node_t dir,
{
struct grub_sfs_obj *obj;
obj = (struct grub_sfs_obj *) ((char *) objc + pos);
char *filename = (char *) (obj->filename);
const char *filename = (const char *) obj->filename;
int len;
enum grub_fshelp_filetype type;
unsigned int block;
@ -412,7 +429,7 @@ grub_sfs_iterate_dir (grub_fshelp_node_t dir,
/* Round up to a multiple of two bytes. */
pos = ((pos + 1) >> 1) << 1;
if (grub_strlen (filename) == 0)
if (filename[0] == 0)
continue;
/* First check if the file was not deleted. */
@ -491,7 +508,10 @@ grub_sfs_open (struct grub_file *file, const char *name)
static grub_err_t
grub_sfs_close (grub_file_t file)
{
grub_free (file->data);
struct grub_sfs_data *data = (struct grub_sfs_data *) file->data;
grub_free (data->label);
grub_free (data);
grub_dl_unref (my_mod);
@ -571,8 +591,15 @@ grub_sfs_label (grub_device_t device, char **label)
data = grub_sfs_mount (disk);
if (data)
*label = data->label;
{
grub_size_t len = grub_strlen (data->label);
*label = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1);
if (*label)
*grub_latin1_to_utf8 ((grub_uint8_t *) *label,
(const grub_uint8_t *) data->label,
len) = '\0';
grub_free (data->label);
}
grub_free (data);
return grub_errno;