Fix panic on invalid multibyte sequence for StrCaseCmp()

Andrew Bartlett abartlet at samba.org
Thu Jul 17 07:25:58 GMT 2003


I've been thinking about the problem of samba calling smb_panic() on invalid
multibyte sequences.  This particuarly occours on StrCaseCmp(), which happens
on every file in a directory in many cases.

This fix simplay makes StrCaseCmp() return != 0 when either string cannot be
converted - that is, any string that cannot be converted can not be equal
to another string.  

This is a starting point - we should possibly change StrCaseCmp() to return
a BOOL, rather than an integer (and change it's name).  We might also want
to fall back to a byte-by-byte comparison if the conversion fails.  
(essentially a case sensitive comparison).

Andrew Bartlett
-------------- next part --------------
? lib/become_root_dummy.c
Index: lib/util_str.c
===================================================================
RCS file: /home/cvs/samba/source/lib/util_str.c,v
retrieving revision 1.47.2.28
diff -u -r1.47.2.28 util_str.c
--- lib/util_str.c	3 Jul 2003 19:11:28 -0000	1.47.2.28
+++ lib/util_str.c	17 Jul 2003 07:14:10 -0000
@@ -181,7 +181,9 @@
 {
 
 	const char * ps, * pt;
-	pstring buf1, buf2;
+	size_t size;
+	smb_ucs2_t *buffer_s, *buffer_t;
+	int ret;
 
 	for (ps = s, pt = t; ; ps++, pt++) {
 		char us, ut;
@@ -206,16 +208,25 @@
 			return +1;
 	}
 
-	/* TODO: Don't do this with a fixed-length buffer.  This could
-	 * still be much more efficient. */
-	/* TODO: Hardcode a char-by-char comparison for UTF-8, which
-	 * can be much faster. */
-	/* TODO: Test case for this! */
-
-	unix_strupper(ps, strlen(ps)+1, buf1, sizeof(buf1));
-	unix_strupper(pt, strlen(pt)+1, buf2, sizeof(buf2));
-
-	return strcmp(buf1, buf2);
+	size = convert_string_allocate(CH_UNIX, CH_UCS2, s, strlen(s),
+				       (void **) &buffer_s);
+	if (size == -1) {
+		return -1; /* Not the right answer, but finding the right one
+			      under this failure case is expensive */
+	}
+	
+	size = convert_string_allocate(CH_UNIX, CH_UCS2, t, strlen(t),
+				       (void **) &buffer_t);
+	if (size == -1) {
+		SAFE_FREE(buffer_s);
+		return +1; /* Not the right answer, but finding the right one
+			      under this failure case is expensive */
+	}
+	
+	ret = strcasecmp_w(buffer_s, buffer_t);
+	SAFE_FREE(buffer_s);
+	SAFE_FREE(buffer_t);
+	return ret;
 }
 
 


More information about the samba-technical mailing list