Allow conversion of characters in Mac remap range (part 2)
The previous patch allowed remapping reserved characters from directory listenings, this patch adds conversion the other direction, allowing opening of files with any of the seven reserved characters. Signed-off-by: Steve French <smfrench@gmail.com> Reviewed-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
This commit is contained in:
parent
b693855fe6
commit
a4153cb1d3
|
@ -319,6 +319,66 @@ cifs_strndup_from_utf16(const char *src, const int maxlen,
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static __le16 convert_to_sfu_char(char src_char)
|
||||||
|
{
|
||||||
|
__le16 dest_char;
|
||||||
|
|
||||||
|
switch (src_char) {
|
||||||
|
case ':':
|
||||||
|
dest_char = cpu_to_le16(UNI_COLON);
|
||||||
|
break;
|
||||||
|
case '*':
|
||||||
|
dest_char = cpu_to_le16(UNI_ASTERISK);
|
||||||
|
break;
|
||||||
|
case '?':
|
||||||
|
dest_char = cpu_to_le16(UNI_QUESTION);
|
||||||
|
break;
|
||||||
|
case '<':
|
||||||
|
dest_char = cpu_to_le16(UNI_LESSTHAN);
|
||||||
|
break;
|
||||||
|
case '>':
|
||||||
|
dest_char = cpu_to_le16(UNI_GRTRTHAN);
|
||||||
|
break;
|
||||||
|
case '|':
|
||||||
|
dest_char = cpu_to_le16(UNI_PIPE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dest_char = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dest_char;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __le16 convert_to_sfm_char(char src_char)
|
||||||
|
{
|
||||||
|
__le16 dest_char;
|
||||||
|
|
||||||
|
switch (src_char) {
|
||||||
|
case ':':
|
||||||
|
dest_char = cpu_to_le16(SFM_COLON);
|
||||||
|
break;
|
||||||
|
case '*':
|
||||||
|
dest_char = cpu_to_le16(SFM_ASTERISK);
|
||||||
|
break;
|
||||||
|
case '?':
|
||||||
|
dest_char = cpu_to_le16(SFM_QUESTION);
|
||||||
|
break;
|
||||||
|
case '<':
|
||||||
|
dest_char = cpu_to_le16(SFM_LESSTHAN);
|
||||||
|
break;
|
||||||
|
case '>':
|
||||||
|
dest_char = cpu_to_le16(SFM_GRTRTHAN);
|
||||||
|
break;
|
||||||
|
case '|':
|
||||||
|
dest_char = cpu_to_le16(SFM_PIPE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dest_char = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dest_char;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert 16 bit Unicode pathname to wire format from string in current code
|
* Convert 16 bit Unicode pathname to wire format from string in current code
|
||||||
* page. Conversion may involve remapping up the six characters that are
|
* page. Conversion may involve remapping up the six characters that are
|
||||||
|
@ -327,7 +387,7 @@ cifs_strndup_from_utf16(const char *src, const int maxlen,
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
cifsConvertToUTF16(__le16 *target, const char *source, int srclen,
|
cifsConvertToUTF16(__le16 *target, const char *source, int srclen,
|
||||||
const struct nls_table *cp, int mapChars)
|
const struct nls_table *cp, int map_chars)
|
||||||
{
|
{
|
||||||
int i, charlen;
|
int i, charlen;
|
||||||
int j = 0;
|
int j = 0;
|
||||||
|
@ -335,39 +395,30 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen,
|
||||||
__le16 dst_char;
|
__le16 dst_char;
|
||||||
wchar_t tmp;
|
wchar_t tmp;
|
||||||
|
|
||||||
if (!mapChars)
|
if (map_chars == NO_MAP_UNI_RSVD)
|
||||||
return cifs_strtoUTF16(target, source, PATH_MAX, cp);
|
return cifs_strtoUTF16(target, source, PATH_MAX, cp);
|
||||||
|
|
||||||
for (i = 0; i < srclen; j++) {
|
for (i = 0; i < srclen; j++) {
|
||||||
src_char = source[i];
|
src_char = source[i];
|
||||||
charlen = 1;
|
charlen = 1;
|
||||||
switch (src_char) {
|
|
||||||
case 0:
|
/* check if end of string */
|
||||||
|
if (src_char == 0)
|
||||||
goto ctoUTF16_out;
|
goto ctoUTF16_out;
|
||||||
case ':':
|
|
||||||
dst_char = cpu_to_le16(UNI_COLON);
|
/* see if we must remap this char */
|
||||||
break;
|
if (map_chars == SFU_MAP_UNI_RSVD)
|
||||||
case '*':
|
dst_char = convert_to_sfu_char(src_char);
|
||||||
dst_char = cpu_to_le16(UNI_ASTERISK);
|
else if (map_chars == SFM_MAP_UNI_RSVD)
|
||||||
break;
|
dst_char = convert_to_sfm_char(src_char);
|
||||||
case '?':
|
else
|
||||||
dst_char = cpu_to_le16(UNI_QUESTION);
|
dst_char = 0;
|
||||||
break;
|
|
||||||
case '<':
|
|
||||||
dst_char = cpu_to_le16(UNI_LESSTHAN);
|
|
||||||
break;
|
|
||||||
case '>':
|
|
||||||
dst_char = cpu_to_le16(UNI_GRTRTHAN);
|
|
||||||
break;
|
|
||||||
case '|':
|
|
||||||
dst_char = cpu_to_le16(UNI_PIPE);
|
|
||||||
break;
|
|
||||||
/*
|
/*
|
||||||
* FIXME: We can not handle remapping backslash (UNI_SLASH)
|
* FIXME: We can not handle remapping backslash (UNI_SLASH)
|
||||||
* until all the calls to build_path_from_dentry are modified,
|
* until all the calls to build_path_from_dentry are modified,
|
||||||
* as they use backslash as separator.
|
* as they use backslash as separator.
|
||||||
*/
|
*/
|
||||||
default:
|
if (dst_char == 0) {
|
||||||
charlen = cp->char2uni(source + i, srclen - i, &tmp);
|
charlen = cp->char2uni(source + i, srclen - i, &tmp);
|
||||||
dst_char = cpu_to_le16(tmp);
|
dst_char = cpu_to_le16(tmp);
|
||||||
|
|
||||||
|
|
|
@ -379,6 +379,14 @@ cifs_convert_path_to_utf16(const char *from, struct cifs_sb_info *cifs_sb)
|
||||||
int len;
|
int len;
|
||||||
const char *start_of_path;
|
const char *start_of_path;
|
||||||
__le16 *to;
|
__le16 *to;
|
||||||
|
int map_type;
|
||||||
|
|
||||||
|
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SFM_CHR)
|
||||||
|
map_type = SFM_MAP_UNI_RSVD;
|
||||||
|
else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
|
||||||
|
map_type = SFU_MAP_UNI_RSVD;
|
||||||
|
else
|
||||||
|
map_type = NO_MAP_UNI_RSVD;
|
||||||
|
|
||||||
/* Windows doesn't allow paths beginning with \ */
|
/* Windows doesn't allow paths beginning with \ */
|
||||||
if (from[0] == '\\')
|
if (from[0] == '\\')
|
||||||
|
@ -386,9 +394,7 @@ cifs_convert_path_to_utf16(const char *from, struct cifs_sb_info *cifs_sb)
|
||||||
else
|
else
|
||||||
start_of_path = from;
|
start_of_path = from;
|
||||||
to = cifs_strndup_to_utf16(start_of_path, PATH_MAX, &len,
|
to = cifs_strndup_to_utf16(start_of_path, PATH_MAX, &len,
|
||||||
cifs_sb->local_nls,
|
cifs_sb->local_nls, map_type);
|
||||||
cifs_sb->mnt_cifs_flags &
|
|
||||||
CIFS_MOUNT_MAP_SPECIAL_CHR);
|
|
||||||
return to;
|
return to;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue