diff options
author | Andrew Bartlett <abartlet@samba.org> | 2003-07-19 00:36:43 +0000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2003-07-19 00:36:43 +0000 |
commit | e45b66ba8a6b6fd669ce7b4f9f8f84f9c26e1575 (patch) | |
tree | d2e2aee395ac04d8687f0d28361b80c8d5fffc1f | |
parent | fb56f58fbc78efbfa6e5a552946ab792e45380a1 (diff) | |
download | samba-e45b66ba8a6b6fd669ce7b4f9f8f84f9c26e1575.tar.gz samba-e45b66ba8a6b6fd669ce7b4f9f8f84f9c26e1575.tar.bz2 samba-e45b66ba8a6b6fd669ce7b4f9f8f84f9c26e1575.zip |
Fix StrCaseCmp() to avoid calling smb_panic() on invalid multibyte strings.
This fix results in
- we no longer use fixed-size buffers in StrCaseCmp (previously limited to
a pstring)
- we return strcmp(s, t) if either of the strings is invalid
- for non-ascii cases, we call iconv twice, not 4 times.
The basic idea with this fix is that if a string is not valid in the currnet
charset, then (unless it is byte-equivilant) it cannot be case-equivilant
to any other string.
This should address the majority of our smb_panic() cases on this matter. It
will not fix them all - we still call unix_strupper(), aka strupper_m()
elsewhere, but this was being called on every file in the directory when
we performed unix_convert().
Tested with the stf unit tests for this routine.
Andrew Bartlett
(This used to be commit 9918fa73145a22b1d7adf001f0a9cf0e1bda4136)
-rw-r--r-- | source3/lib/util_str.c | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 96fbc3f124..7bf43de5f3 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -181,7 +181,9 @@ int StrCaseCmp(const char *s, const char *t) { 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 @@ int StrCaseCmp(const char *s, const char *t) 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; } |