kern/59765: msdosfs long file name matching should be case insensitve

R. Imura imura at ryu16.org
Mon Dec 1 06:50:22 PST 2003


The following reply was made to PR kern/59765; it has been noted by GNATS.

From: "R. Imura" <imura at ryu16.org>
To: FreeBSD-gnats-submit at FreeBSD.org
Cc: Max Khon <fjoe at FreeBSD.org>
Subject: Re: kern/59765: msdosfs long file name matching should be case insensitve
Date: Mon, 1 Dec 2003 23:43:13 +0900

 On Sat, Nov 29, 2003 at 02:42:15AM +0900, Ryuichiro Imura wrote:
 > 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.
 
 I noticed the previous patch is insufficient.
 Since convertion tables are shared by other file systems, if you mount
 msdosfs after mount cd9660, there aren't any upper/lower tables.
 We need to create upper/lower table for every file systems and need to
 reserve it for msdosfs.  Now I'd like to add a new function which wraps
 upper/lower operations, and replace existent kiconv functions with it.
 
 - R. Imura
 
 Index: lib/libkiconv/Makefile
 ===================================================================
 RCS file: /home/ncvs/src/lib/libkiconv/Makefile,v
 retrieving revision 1.1
 diff -u -r1.1 Makefile
 --- lib/libkiconv/Makefile	26 Sep 2003 20:26:20 -0000	1.1
 +++ lib/libkiconv/Makefile	1 Dec 2003 14:41:21 -0000
 @@ -10,6 +10,7 @@
  MAN=		kiconv.3
  
  MLINKS+=	kiconv.3 kiconv_add_xlat16_cspair.3 \
 +		kiconv.3 kiconv_add_xlat16_cspairs.3 \
  		kiconv.3 kiconv_add_xlat16_table.3
  
  CFLAGS+=	-I${.CURDIR}/../../sys
 Index: lib/libkiconv/kiconv.3
 ===================================================================
 RCS file: /home/ncvs/src/lib/libkiconv/kiconv.3,v
 retrieving revision 1.2
 diff -u -r1.2 kiconv.3
 --- lib/libkiconv/kiconv.3	5 Oct 2003 13:39:28 -0000	1.2
 +++ lib/libkiconv/kiconv.3	30 Nov 2003 23:28:05 -0000
 @@ -30,6 +30,7 @@
  .Os
  .Sh NAME
  .Nm kiconv_add_xlat16_cspair ,
 +.Nm kiconv_add_xlat16_cspairs ,
  .Nm kiconv_add_xlat16_table
  .Nd Kernel side iconv library
  .Sh LIBRARY
 @@ -43,6 +44,11 @@
  .Fa "int flag"
  .Fc
  .Ft int
 +.Fo kiconv_add_xlat16_cspairs
 +.Fa "const char *foreigncode"
 +.Fa "const char *localcode"
 +.Fc
 +.Ft int
  .Fo kiconv_add_xlat16_table
  .Fa "const char *tocode"
  .Fa "const char *fromcode"
 @@ -92,6 +98,17 @@
  .Pp
  A tolower/toupper conversion is limited to single-byte characters.
  .Pp 
 +.Fn kiconv_add_xlat16_cspairs
 +defines two conversion tables which are from
 +.Ar localcode
 +to
 +.Ar foreigncode
 +and from
 +.Ar foreigncode
 +to
 +.Ar localcode .
 +This conversion tables also contain both of tolower and toupper tables.
 +.Pp
  .Fn kiconv_add_xlat16_table
  defines a conversion table directly pointed by
  .Ar data
 Index: lib/libkiconv/xlat16_iconv.c
 ===================================================================
 RCS file: /home/ncvs/src/lib/libkiconv/xlat16_iconv.c,v
 retrieving revision 1.1
 diff -u -r1.1 xlat16_iconv.c
 --- lib/libkiconv/xlat16_iconv.c	26 Sep 2003 20:26:20 -0000	1.1
 +++ lib/libkiconv/xlat16_iconv.c	30 Nov 2003 23:37:10 -0000
 @@ -113,6 +113,23 @@
  	return (-1);
  }
  
 +int
 +kiconv_add_xlat16_cspairs(const char *foreigncode, const char *localcode)
 +{
 +	int error;
 +
 +	error = kiconv_add_xlat16_cspair(foreigncode, localcode,
 +	    KICONV_FROM_LOWER | KICONV_FROM_UPPER);
 +	if (error)
 +		return (error);
 +	error = kiconv_add_xlat16_cspair(localcode, foreigncode,
 +	    KICONV_LOWER | KICONV_UPPER);
 +	if (error)
 +		return (error);
 +	
 +	return (0);
 +}
 +
  static struct xlat16_table
  kiconv_xlat16_open(const char *tocode, const char *fromcode, int lcase)
  {
 Index: sbin/mount_cd9660/mount_cd9660.c
 ===================================================================
 RCS file: /home/ncvs/src/sbin/mount_cd9660/mount_cd9660.c,v
 retrieving revision 1.25
 diff -u -r1.25 mount_cd9660.c
 --- sbin/mount_cd9660/mount_cd9660.c	4 Nov 2003 21:04:14 -0000	1.25
 +++ sbin/mount_cd9660/mount_cd9660.c	30 Nov 2003 23:28:06 -0000
 @@ -255,10 +255,7 @@
  	strncpy(args->cs_disk, ENCODING_UNICODE, ICONV_CSNMAXLEN);
  	strncpy(args->cs_local, kiconv_quirkcs(localcs, KICONV_VENDOR_MICSFT),
  	    ICONV_CSNMAXLEN);
 -	error = kiconv_add_xlat16_cspair(args->cs_local, args->cs_disk, 0);
 -	if (error)
 -		return (-1);
 -	error = kiconv_add_xlat16_cspair(args->cs_disk, args->cs_local, 0);
 +	error = kiconv_add_xlat16_cspairs(args->cs_disk, args->cs_local);
  	if (error)
  		return (-1);
  
 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	30 Nov 2003 23:28:06 -0000
 @@ -339,17 +339,11 @@
  	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);
 -	if (error)
 -		return (-1);
 -	error = kiconv_add_xlat16_cspair(args->cs_local, args->cs_win, 0);
 +	error = kiconv_add_xlat16_cspairs(args->cs_win, args->cs_local);
  	if (error)
  		return (-1);
  	if (args->cs_dos) {
 -		error = kiconv_add_xlat16_cspair(args->cs_dos, args->cs_local, KICONV_FROM_UPPER);
 -		if (error)
 -			return (-1);
 -		error = kiconv_add_xlat16_cspair(args->cs_local, args->cs_dos, KICONV_LOWER);
 +		error = kiconv_add_xlat16_cspairs(args->cs_dos, args->cs_local);
  		if (error)
  			return (-1);
  	} else {
 Index: sbin/mount_ntfs/mount_ntfs.c
 ===================================================================
 RCS file: /home/ncvs/src/sbin/mount_ntfs/mount_ntfs.c,v
 retrieving revision 1.9
 diff -u -r1.9 mount_ntfs.c
 --- sbin/mount_ntfs/mount_ntfs.c	26 Sep 2003 20:26:21 -0000	1.9
 +++ sbin/mount_ntfs/mount_ntfs.c	30 Nov 2003 23:28:06 -0000
 @@ -275,10 +275,7 @@
  	if ((pargs->cs_ntfs = malloc(ICONV_CSNMAXLEN)) == NULL)
  		return (-1);
  	strncpy(pargs->cs_ntfs, ENCODING_UNICODE, ICONV_CSNMAXLEN);
 -	error = kiconv_add_xlat16_cspair(pargs->cs_local, pargs->cs_ntfs, 0);
 -	if (error)
 -		return (-1);
 -	error = kiconv_add_xlat16_cspair(pargs->cs_ntfs, pargs->cs_local, 0);
 +	error = kiconv_add_xlat16_cspairs(pargs->cs_ntfs, pargs->cs_local);
  	if (error)
  		return (-1);
  
 Index: sbin/mount_udf/mount_udf.c
 ===================================================================
 RCS file: /home/ncvs/src/sbin/mount_udf/mount_udf.c,v
 retrieving revision 1.8
 diff -u -r1.8 mount_udf.c
 --- sbin/mount_udf/mount_udf.c	24 Nov 2003 16:14:32 -0000	1.8
 +++ sbin/mount_udf/mount_udf.c	30 Nov 2003 23:28:07 -0000
 @@ -172,14 +172,9 @@
  		return (-1);
  	strncpy(*cs_disk, ENCODING_UNICODE, ICONV_CSNMAXLEN);
  	strncpy(*cs_local, localcs, ICONV_CSNMAXLEN);
 -	error = kiconv_add_xlat16_cspair(*cs_local, *cs_disk, 0);
 +	error = kiconv_add_xlat16_cspairs(*cs_disk, *cs_local);
  	if (error)
  		return (-1);
 -#if 0
 -	error = kiconv_add_xlat16_cspair(*cs_disk, *cs_local, 0);
 -	if (error)
 -		return (-1);
 -#endif
  
  	return (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	30 Nov 2003 23:28:06 -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 in 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 {
 Index: sys/sys/iconv.h
 ===================================================================
 RCS file: /home/ncvs/src/sys/sys/iconv.h,v
 retrieving revision 1.7
 diff -u -r1.7 iconv.h
 --- sys/sys/iconv.h	5 Nov 2003 06:27:40 -0000	1.7
 +++ sys/sys/iconv.h	30 Nov 2003 23:35:36 -0000
 @@ -92,6 +103,7 @@
  
  int   kiconv_add_xlat_table(const char *, const char *, const u_char *);
  int   kiconv_add_xlat16_cspair(const char *, const char *, int);
 +int   kiconv_add_xlat16_cspairs(const char *, const char *);
  int   kiconv_add_xlat16_table(const char *, const char *, const void *, int);
  const char *kiconv_quirkcs(const char *, int);
  


More information about the freebsd-bugs mailing list