From owner-freebsd-bugs@FreeBSD.ORG Fri Nov 28 09:50:14 2003 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 9A19B16A4CF for ; Fri, 28 Nov 2003 09:50:14 -0800 (PST) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 05D6443FE1 for ; Fri, 28 Nov 2003 09:50:09 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.9/8.12.9) with ESMTP id hASHo8FY089440 for ; Fri, 28 Nov 2003 09:50:08 -0800 (PST) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.9/8.12.9/Submit) id hASHo8Jv089439; Fri, 28 Nov 2003 09:50:08 -0800 (PST) (envelope-from gnats) Resent-Date: Fri, 28 Nov 2003 09:50:08 -0800 (PST) Resent-Message-Id: <200311281750.hASHo8Jv089439@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Ryuichiro Imura Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 37DE016A4CE; Fri, 28 Nov 2003 09:42:20 -0800 (PST) Received: from mail.ryu16.org (YahooBB219005044050.bbtec.net [219.5.44.50]) by mx1.FreeBSD.org (Postfix) with ESMTP id A170A43F85; Fri, 28 Nov 2003 09:42:17 -0800 (PST) (envelope-from imura@ryu16.org) Received: from redeye.xt.ryu16.org (localhost [127.0.0.1]) by mail.ryu16.org (8.12.9p1/8.12.9) with ESMTP id hASHgGmh053767; Sat, 29 Nov 2003 02:42:16 +0900 (JST) (envelope-from imura@redeye.xt.ryu16.org) Received: (from imura@localhost) by redeye.xt.ryu16.org (8.12.9p1/8.12.9/Submit) id hASHgFIX053766; Sat, 29 Nov 2003 02:42:15 +0900 (JST) (envelope-from imura) Message-Id: <200311281742.hASHgFIX053766@redeye.xt.ryu16.org> Date: Sat, 29 Nov 2003 02:42:15 +0900 (JST) From: Ryuichiro Imura To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 cc: Max Khon Subject: kern/59765: msdosfs long file name matching should be case insensitve X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: Ryuichiro Imura List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 28 Nov 2003 17:50:14 -0000 >Number: 59765 >Category: kern >Synopsis: msdosfs long file name matching should be case insensitve >Confidential: no >Severity: serious >Priority: high >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Fri Nov 28 09:50:06 PST 2003 >Closed-Date: >Last-Modified: >Originator: Ryuichiro Imura >Release: FreeBSD 5.2-BETA i186 >Organization: >Environment: System: FreeBSD bluewind.xt.ryu16.org 5.2-BETA FreeBSD 5.2-BETA #22: Wed Nov 26 02:09:08 JST 2003 root@bluewind.xt.ryu16.org:/usr/obj/usr/src/sys/BLUE i386 >Description: Although msdosfs's long file name matching should be case insensitive, current code has been changed to do in case sensitive after kiconv(3) changes. Sorry for that. Just FYI, the first problem was reported at FreeBSD-users-jp@jp.freebsd.org list. >How-To-Repeat: >Fix: Fixing this problem should be very easy if nobody using kiconv feature, but sad to say that iconv_xlat16.c has a bug when using KICONV_FROM_XX with UCS-2, This patch fixes this problem and iconv_xlat16.c's bug. Index: sbin/mount_msdosfs/mount_msdosfs.c =================================================================== RCS file: /home/ncvs/src/sbin/mount_msdosfs/mount_msdosfs.c,v retrieving revision 1.31 diff -u -r1.31 mount_msdosfs.c --- sbin/mount_msdosfs/mount_msdosfs.c 23 Oct 2003 16:09:20 -0000 1.31 +++ sbin/mount_msdosfs/mount_msdosfs.c 24 Nov 2003 06:34:07 -0000 @@ -339,7 +339,7 @@ if ((args->cs_win = malloc(ICONV_CSNMAXLEN)) == NULL) return (-1); strncpy(args->cs_win, ENCODING_UNICODE, ICONV_CSNMAXLEN); - error = kiconv_add_xlat16_cspair(args->cs_win, args->cs_local, 0); + error = kiconv_add_xlat16_cspair(args->cs_win, args->cs_local, KICONV_FROM_LOWER); if (error) return (-1); error = kiconv_add_xlat16_cspair(args->cs_local, args->cs_win, 0); Index: sys/fs/msdosfs/msdosfs_conv.c =================================================================== RCS file: /home/ncvs/src/sys/fs/msdosfs/msdosfs_conv.c,v retrieving revision 1.34 diff -u -r1.34 msdosfs_conv.c --- sys/fs/msdosfs/msdosfs_conv.c 26 Sep 2003 20:26:22 -0000 1.34 +++ sys/fs/msdosfs/msdosfs_conv.c 28 Nov 2003 17:37:35 -0000 @@ -800,10 +800,12 @@ for (np = dirbuf.d_name; unlen > 0 && len > 0;) { /* - * Should comparison be case insensitive? + * Comparison must be case insensitive, because FAT disallows + * to look up or create files case sensitive even when + * it's a long file name. */ - c1 = unix2winchr((const u_char **)&np, (size_t *)&len, 0, pmp); - c2 = unix2winchr(&un, (size_t *)&unlen, 0, pmp); + c1 = unix2winchr((const u_char **)&np, (size_t *)&len, LCASE_BASE, pmp); + c2 = unix2winchr(&un, (size_t *)&unlen, LCASE_BASE, pmp); if (c1 != c2) return -2; } Index: sys/libkern/iconv_xlat16.c =================================================================== RCS file: /home/ncvs/src/sys/libkern/iconv_xlat16.c,v retrieving revision 1.1 diff -u -r1.1 iconv_xlat16.c --- sys/libkern/iconv_xlat16.c 26 Sep 2003 20:26:24 -0000 1.1 +++ sys/libkern/iconv_xlat16.c 24 Nov 2003 17:32:09 -0000 @@ -96,11 +96,11 @@ struct iconv_xlat16 *dp = (struct iconv_xlat16*)d2p; const char *src; char *dst; - int ret = 0; + int nullin, ret = 0; size_t in, on, ir, or, inlen; uint32_t code; u_char u, l; - u_int16_t c1, c2; + uint16_t c1, c2; if (inbuf == NULL || *inbuf == NULL || outbuf == NULL || *outbuf == NULL) return (0); @@ -146,7 +146,8 @@ } } - if ((inlen == 1) && (code & XLAT16_ACCEPT_NULL_IN)) { + nullin = (code & XLAT16_ACCEPT_NULL_IN) ? 1 : 0; + if (inlen == 1 && nullin) { /* * XLAT16_ACCEPT_NULL_IN requires inbuf has 2byte */ @@ -157,6 +158,14 @@ /* * now start translation */ + if ((casetype == KICONV_FROM_LOWER && code & XLAT16_HAS_FROM_LOWER_CASE) || + (casetype == KICONV_FROM_UPPER && code & XLAT16_HAS_FROM_UPPER_CASE)) { + c2 = (u_char)(code >> 16); + c1 = c2 & 0x80 ? 0x100 : 0; + c2 = c2 & 0x80 ? c2 & 0x7f : c2; + code = dp->d_table[c1][c2]; + } + u = (u_char)(code >> 8); l = (u_char)code; @@ -184,9 +193,6 @@ if ((casetype == KICONV_LOWER && code & XLAT16_HAS_LOWER_CASE) || (casetype == KICONV_UPPER && code & XLAT16_HAS_UPPER_CASE)) *dst++ = (u_char)(code >> 16); - else if ((casetype == KICONV_FROM_LOWER && code & XLAT16_HAS_FROM_LOWER_CASE) || - (casetype == KICONV_FROM_UPPER && code & XLAT16_HAS_FROM_UPPER_CASE)) - *dst++ = dp->d_table[0][(u_char)(code >> 16)]; else *dst++ = l; or--; @@ -197,8 +203,7 @@ * there is a case that inbuf char is a single * byte char while inlen == 2 */ - if ((u_char)*(src+1) == 0 && - (code & XLAT16_ACCEPT_NULL_IN) == 0 ) { + if ((u_char)*(src+1) == 0 && !nullin ) { src++; ir--; } else { >Release-Note: >Audit-Trail: >Unformatted: