+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
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
#include <grub/dl.h>
#include <grub/types.h>
#include <grub/fshelp.h>
+#include <grub/charset.h>
GRUB_MOD_LICENSE ("GPLv3+");
data->disk = disk;
data->label = grub_strdup ((char *) (rootobjc->objects[0].filename));
+ grub_free (rootobjc_data);
return data;
fail:
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);
{
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;
/* 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. */
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);
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;