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/cifs/cifs_unicode.c | |
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/cifs/cifs_unicode.c')
-rw-r--r-- | fs/cifs/cifs_unicode.c | 76 |
1 files changed, 76 insertions, 0 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 | |||