fat/nls: Fix handling of utf8 invalid char
With utf8 option, vfat allowed the duplicated filenames. Normal nls returns -EINVAL for invalid char. But utf8s_to_utf16s() skipped the invalid char historically. So, this changes the utf8s_to_utf16s() directly to return -EINVAL for invalid char, because vfat is only user of it. mkdir /mnt/fatfs FILENAME=`echo -ne "invalidutf8char_\\0341_endofchar"` echo "Using filename: $FILENAME" dd if=/dev/zero of=fatfs bs=512 count=128 mkdosfs -F 32 fatfs mount -o loop,utf8 fatfs /mnt/fatfs touch "/mnt/fatfs/$FILENAME" umount /mnt/fatfs mount -o loop,utf8 fatfs /mnt/fatfs touch "/mnt/fatfs/$FILENAME" ls -l /mnt/fatfs umount /mnt/fatfs ---- And the output is: Using filename: invalidutf8char_\0341_endofchar 128+0 records in 128+0 records out 65536 bytes (66 kB) copied, 0.000388118 s, 169 MB/s mkdosfs 2.11 (12 Mar 2005) total 0 -rwxr-xr-x 1 root root 0 Jun 28 19:46 invalidutf8char__endofchar -rwxr-xr-x 1 root root 0 Jun 28 19:46 invalidutf8char__endofchar Tested-by: Marton Balint <cus@fazekas.hu> Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
This commit is contained in:
parent
ed680c4ad4
commit
67638e4043
2 changed files with 8 additions and 15 deletions
|
@ -499,17 +499,10 @@ xlate_to_uni(const unsigned char *name, int len, unsigned char *outname,
|
||||||
int charlen;
|
int charlen;
|
||||||
|
|
||||||
if (utf8) {
|
if (utf8) {
|
||||||
int name_len = strlen(name);
|
*outlen = utf8s_to_utf16s(name, len, (wchar_t *)outname);
|
||||||
|
if (*outlen < 0)
|
||||||
*outlen = utf8s_to_utf16s(name, PATH_MAX, (wchar_t *) outname);
|
return *outlen;
|
||||||
|
else if (*outlen > 255)
|
||||||
/*
|
|
||||||
* We stripped '.'s before and set len appropriately,
|
|
||||||
* but utf8s_to_utf16s doesn't care about len
|
|
||||||
*/
|
|
||||||
*outlen -= (name_len - len);
|
|
||||||
|
|
||||||
if (*outlen > 255)
|
|
||||||
return -ENAMETOOLONG;
|
return -ENAMETOOLONG;
|
||||||
|
|
||||||
op = &outname[*outlen * sizeof(wchar_t)];
|
op = &outname[*outlen * sizeof(wchar_t)];
|
||||||
|
|
|
@ -124,10 +124,10 @@ int utf8s_to_utf16s(const u8 *s, int len, wchar_t *pwcs)
|
||||||
while (*s && len > 0) {
|
while (*s && len > 0) {
|
||||||
if (*s & 0x80) {
|
if (*s & 0x80) {
|
||||||
size = utf8_to_utf32(s, len, &u);
|
size = utf8_to_utf32(s, len, &u);
|
||||||
if (size < 0) {
|
if (size < 0)
|
||||||
/* Ignore character and move on */
|
return -EINVAL;
|
||||||
size = 1;
|
|
||||||
} else if (u >= PLANE_SIZE) {
|
if (u >= PLANE_SIZE) {
|
||||||
u -= PLANE_SIZE;
|
u -= PLANE_SIZE;
|
||||||
*op++ = (wchar_t) (SURROGATE_PAIR |
|
*op++ = (wchar_t) (SURROGATE_PAIR |
|
||||||
((u >> 10) & SURROGATE_BITS));
|
((u >> 10) & SURROGATE_BITS));
|
||||||
|
|
Loading…
Reference in a new issue