diff options
author | Jeff Layton <jlayton@redhat.com> | 2011-01-20 13:36:51 -0500 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2011-01-20 16:48:00 -0500 |
commit | 84cdf74e8096a10dd6acbb870dd404b92f07a756 (patch) | |
tree | 3cae46e567fab0649bb5696f4097d8072b0f9645 /fs | |
parent | ba2dbf30df210b519bdd8d34ac2ecaaeeef34c44 (diff) |
cifs: fix unaligned accesses in cifsConvertToUCS
Move cifsConvertToUCS to cifs_unicode.c where all of the other unicode
related functions live. Have it store mapped characters in 'temp' and
then use put_unaligned_le16 to copy it to the target buffer. Also fix
the comments to match kernel coding style.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Acked-by: Pavel Shilovsky <piastryyy@gmail.com>
Reviewed-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/cifs/cifs_unicode.c | 76 | ||||
-rw-r--r-- | fs/cifs/misc.c | 71 |
2 files changed, 76 insertions, 71 deletions
diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c index 5f6e71857be6..fc0fd4fde306 100644 --- a/fs/cifs/cifs_unicode.c +++ b/fs/cifs/cifs_unicode.c | |||
@@ -257,3 +257,79 @@ cifs_strndup_from_ucs(const char *src, const int maxlen, const bool is_unicode, | |||
257 | return dst; | 257 | return dst; |
258 | } | 258 | } |
259 | 259 | ||
260 | /* | ||
261 | * Convert 16 bit Unicode pathname to wire format from string in current code | ||
262 | * page. Conversion may involve remapping up the six characters that are | ||
263 | * only legal in POSIX-like OS (if they are present in the string). Path | ||
264 | * names are little endian 16 bit Unicode on the wire | ||
265 | */ | ||
266 | int | ||
267 | cifsConvertToUCS(__le16 *target, const char *source, int maxlen, | ||
268 | const struct nls_table *cp, int mapChars) | ||
269 | { | ||
270 | int i, j, charlen; | ||
271 | int len_remaining = maxlen; | ||
272 | char src_char; | ||
273 | __u16 temp; | ||
274 | |||
275 | if (!mapChars) | ||
276 | return cifs_strtoUCS(target, source, PATH_MAX, cp); | ||
277 | |||
278 | for (i = 0, j = 0; i < maxlen; j++) { | ||
279 | src_char = source[i]; | ||
280 | switch (src_char) { | ||
281 | case 0: | ||
282 | put_unaligned_le16(0, &target[j]); | ||
283 | goto ctoUCS_out; | ||
284 | case ':': | ||
285 | temp = UNI_COLON; | ||
286 | break; | ||
287 | case '*': | ||
288 | temp = UNI_ASTERIK; | ||
289 | break; | ||
290 | case '?': | ||
291 | temp = UNI_QUESTION; | ||
292 | break; | ||
293 | case '<': | ||
294 | temp = UNI_LESSTHAN; | ||
295 | break; | ||
296 | case '>': | ||
297 | temp = UNI_GRTRTHAN; | ||
298 | break; | ||
299 | case '|': | ||
300 | temp = UNI_PIPE; | ||
301 | break; | ||
302 | /* | ||
303 | * FIXME: We can not handle remapping backslash (UNI_SLASH) | ||
304 | * until all the calls to build_path_from_dentry are modified, | ||
305 | * as they use backslash as separator. | ||
306 | */ | ||
307 | default: | ||
308 | charlen = cp->char2uni(source+i, len_remaining, | ||
309 | &temp); | ||
310 | /* | ||
311 | * if no match, use question mark, which at least in | ||
312 | * some cases serves as wild card | ||
313 | */ | ||
314 | if (charlen < 1) { | ||
315 | temp = 0x003f; | ||
316 | charlen = 1; | ||
317 | } | ||
318 | len_remaining -= charlen; | ||
319 | /* | ||
320 | * character may take more than one byte in the source | ||
321 | * string, but will take exactly two bytes in the | ||
322 | * target string | ||
323 | */ | ||
324 | i += charlen; | ||
325 | continue; | ||
326 | } | ||
327 | put_unaligned_le16(temp, &target[j]); | ||
328 | i++; /* move to next char in source string */ | ||
329 | len_remaining--; | ||
330 | } | ||
331 | |||
332 | ctoUCS_out: | ||
333 | return i; | ||
334 | } | ||
335 | |||
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 09bfcf08a90f..a09e077ba925 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
@@ -637,77 +637,6 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length) | |||
637 | return; | 637 | return; |
638 | } | 638 | } |
639 | 639 | ||
640 | /* Convert 16 bit Unicode pathname to wire format from string in current code | ||
641 | page. Conversion may involve remapping up the seven characters that are | ||
642 | only legal in POSIX-like OS (if they are present in the string). Path | ||
643 | names are little endian 16 bit Unicode on the wire */ | ||
644 | int | ||
645 | cifsConvertToUCS(__le16 *target, const char *source, int maxlen, | ||
646 | const struct nls_table *cp, int mapChars) | ||
647 | { | ||
648 | int i, j, charlen; | ||
649 | int len_remaining = maxlen; | ||
650 | char src_char; | ||
651 | __u16 temp; | ||
652 | |||
653 | if (!mapChars) | ||
654 | return cifs_strtoUCS(target, source, PATH_MAX, cp); | ||
655 | |||
656 | for (i = 0, j = 0; i < maxlen; j++) { | ||
657 | src_char = source[i]; | ||
658 | switch (src_char) { | ||
659 | case 0: | ||
660 | target[j] = 0; | ||
661 | goto ctoUCS_out; | ||
662 | case ':': | ||
663 | target[j] = cpu_to_le16(UNI_COLON); | ||
664 | break; | ||
665 | case '*': | ||
666 | target[j] = cpu_to_le16(UNI_ASTERIK); | ||
667 | break; | ||
668 | case '?': | ||
669 | target[j] = cpu_to_le16(UNI_QUESTION); | ||
670 | break; | ||
671 | case '<': | ||
672 | target[j] = cpu_to_le16(UNI_LESSTHAN); | ||
673 | break; | ||
674 | case '>': | ||
675 | target[j] = cpu_to_le16(UNI_GRTRTHAN); | ||
676 | break; | ||
677 | case '|': | ||
678 | target[j] = cpu_to_le16(UNI_PIPE); | ||
679 | break; | ||
680 | /* BB We can not handle remapping slash until | ||
681 | all the calls to build_path_from_dentry | ||
682 | are modified, as they use slash as separator BB */ | ||
683 | /* case '\\': | ||
684 | target[j] = cpu_to_le16(UNI_SLASH); | ||
685 | break;*/ | ||
686 | default: | ||
687 | charlen = cp->char2uni(source+i, | ||
688 | len_remaining, &temp); | ||
689 | /* if no match, use question mark, which | ||
690 | at least in some cases servers as wild card */ | ||
691 | if (charlen < 1) { | ||
692 | target[j] = cpu_to_le16(0x003f); | ||
693 | charlen = 1; | ||
694 | } else | ||
695 | target[j] = cpu_to_le16(temp); | ||
696 | len_remaining -= charlen; | ||
697 | /* character may take more than one byte in the | ||
698 | the source string, but will take exactly two | ||
699 | bytes in the target string */ | ||
700 | i += charlen; | ||
701 | continue; | ||
702 | } | ||
703 | i++; /* move to next char in source string */ | ||
704 | len_remaining--; | ||
705 | } | ||
706 | |||
707 | ctoUCS_out: | ||
708 | return i; | ||
709 | } | ||
710 | |||
711 | void | 640 | void |
712 | cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb) | 641 | cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb) |
713 | { | 642 | { |