[PATCH] Re: Fix panic on invalid multibyte sequence for StrCaseCmp()
Andrew Bartlett
abartlet at samba.org
Thu Jul 17 23:47:39 GMT 2003
On Thu, Jul 17, 2003 at 07:25:58AM +0000, Andrew Bartlett wrote:
> 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).
The attached patch returns the byte-by-byte value if the string cannot be
converted, which considering the circumstances in pretty reasonable.
It also allows for two matching illigal strings.
Andrew Bartlett
-------------- next part --------------
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 23:43:07 -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,27 @@
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 strcmp(s, t);
+ /* Not quite the right answer, but finding the right one
+ under this failure case is expensive, and it's pretty close */
+ }
+
+ size = convert_string_allocate(CH_UNIX, CH_UCS2, t, strlen(t),
+ (void **) &buffer_t);
+ if (size == -1) {
+ SAFE_FREE(buffer_s);
+ return strcmp(s, t);
+ /* Not quite the right answer, but finding the right one
+ under this failure case is expensive, and it's pretty close */
+ }
+
+ 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