@@ -1051,7 +1051,7 @@ static int do_label(struct f2fs_sb_info *sbi)
if (!c.vol_label) {
char label[MAX_VOLUME_NAME];
- utf16_to_utf8(label, sb->volume_name,
+ utf16_to_utf8(label, (const char *)sb->volume_name,
MAX_VOLUME_NAME, MAX_VOLUME_NAME);
MSG(0, "Info: volume label = %s\n", label);
return 0;
@@ -1062,7 +1062,7 @@ static int do_label(struct f2fs_sb_info *sbi)
return -1;
}
- utf8_to_utf16(sb->volume_name, (const char *)c.vol_label,
+ utf8_to_utf16((char *)sb->volume_name, (const char *)c.vol_label,
MAX_VOLUME_NAME, strlen(c.vol_label));
update_superblock(sb, SB_MASK_ALL);
@@ -365,7 +365,7 @@ void print_node_info(struct f2fs_sb_info *sbi,
}
}
-static void DISP_label(uint16_t *name)
+static void DISP_label(const char *name)
{
char buffer[MAX_VOLUME_NAME];
@@ -391,7 +391,7 @@ printout:
DISP_u32(sb, magic);
DISP_u32(sb, major_ver);
- DISP_label(sb->volume_name);
+ DISP_label((const char *)sb->volume_name);
DISP_u32(sb, minor_ver);
DISP_u32(sb, log_sectorsize);
@@ -1430,8 +1430,8 @@ enum {
SSR
};
-extern int utf8_to_utf16(uint16_t *, const char *, size_t, size_t);
-extern int utf16_to_utf8(char *, const uint16_t *, size_t, size_t);
+extern int utf8_to_utf16(char *, const char *, size_t, size_t);
+extern int utf16_to_utf8(char *, const char *, size_t, size_t);
extern int log_base_2(uint32_t);
extern unsigned int addrs_per_inode(struct f2fs_inode *);
extern unsigned int addrs_per_block(struct f2fs_inode *);
@@ -115,31 +115,40 @@ static uint16_t *wchar_to_utf16(uint16_t *output, wchar_t wc, size_t outsize)
return output + 2;
}
-int utf8_to_utf16(uint16_t *output, const char *input, size_t outsize,
+int utf8_to_utf16(char *output, const char *input, size_t outsize,
size_t insize)
{
const char *inp = input;
- uint16_t *outp = output;
+ uint16_t *outp;
wchar_t wc;
+ uint16_t *volume_name = calloc(sizeof(uint16_t), MAX_VOLUME_NAME);
+
+ if (!volume_name)
+ return -ENOMEM;
+
+ outp = volume_name;
while ((size_t)(inp - input) < insize && *inp) {
inp = utf8_to_wchar(inp, &wc, insize - (inp - input));
if (inp == NULL) {
DBG(0, "illegal UTF-8 sequence\n");
+ free(volume_name);
return -EILSEQ;
}
- outp = wchar_to_utf16(outp, wc, outsize - (outp - output));
+ outp = wchar_to_utf16(outp, wc, outsize - (outp - volume_name));
if (outp == NULL) {
DBG(0, "name is too long\n");
+ free(volume_name);
return -ENAMETOOLONG;
}
}
*outp = cpu_to_le16(0);
+ memcpy(output, volume_name, sizeof(uint16_t) * MAX_VOLUME_NAME);
+ free(volume_name);
return 0;
}
-static const uint16_t *utf16_to_wchar(const uint16_t *input, wchar_t *wc,
- size_t insize)
+static uint16_t *utf16_to_wchar(uint16_t *input, wchar_t *wc, size_t insize)
{
if ((le16_to_cpu(input[0]) & 0xfc00) == 0xd800) {
if (insize < 2 || (le16_to_cpu(input[1]) & 0xfc00) != 0xdc00)
@@ -201,26 +210,36 @@ static char *wchar_to_utf8(char *output, wchar_t wc, size_t outsize)
return output;
}
-int utf16_to_utf8(char *output, const uint16_t *input, size_t outsize,
+int utf16_to_utf8(char *output, const char *input, size_t outsize,
size_t insize)
{
- const uint16_t *inp = input;
char *outp = output;
wchar_t wc;
+ uint16_t *inp;
+ uint16_t *volume_name = calloc(sizeof(uint16_t), MAX_VOLUME_NAME);
+
+ if (!volume_name)
+ return -ENOMEM;
+
+ memcpy(volume_name, input, sizeof(uint16_t) * MAX_VOLUME_NAME);
+ inp = volume_name;
- while ((size_t)(inp - input) < insize && le16_to_cpu(*inp)) {
- inp = utf16_to_wchar(inp, &wc, insize - (inp - input));
+ while ((size_t)(inp - volume_name) < insize && le16_to_cpu(*inp)) {
+ inp = utf16_to_wchar(inp, &wc, insize - (inp - volume_name));
if (inp == NULL) {
DBG(0, "illegal UTF-16 sequence\n");
+ free(volume_name);
return -EILSEQ;
}
outp = wchar_to_utf8(outp, wc, outsize - (outp - output));
if (outp == NULL) {
DBG(0, "name is too long\n");
+ free(volume_name);
return -ENAMETOOLONG;
}
}
*outp = '\0';
+ free(volume_name);
return 0;
}
@@ -512,7 +512,7 @@ static int f2fs_prepare_super_block(void)
if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
c.chksum_seed = f2fs_cal_crc32(~0, sb->uuid, sizeof(sb->uuid));
- utf8_to_utf16(sb->volume_name, (const char *)c.vol_label,
+ utf8_to_utf16((char *)sb->volume_name, (const char *)c.vol_label,
MAX_VOLUME_NAME, strlen(c.vol_label));
set_sb(node_ino, 1);
set_sb(meta_ino, 2);
Let's avoid memory alignment of sb->volume_name. Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> --- fsck/main.c | 4 ++-- fsck/mount.c | 4 ++-- include/f2fs_fs.h | 4 ++-- lib/libf2fs.c | 37 ++++++++++++++++++++++++++++--------- mkfs/f2fs_format.c | 2 +- 5 files changed, 35 insertions(+), 16 deletions(-)