diff options
author | Jeremy Allison <jra@samba.org> | 1998-10-20 20:08:35 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 1998-10-20 20:08:35 +0000 |
commit | e094a36a98db8299d7b2b21c8f8ee0ee97e57030 (patch) | |
tree | 37458cb454594057f4a43929518336d304defabb /source3/lib/util.c | |
parent | 1ebeb54932de01323356e8201d465656b8723d46 (diff) | |
download | samba-e094a36a98db8299d7b2b21c8f8ee0ee97e57030.tar.gz samba-e094a36a98db8299d7b2b21c8f8ee0ee97e57030.tar.xz samba-e094a36a98db8299d7b2b21c8f8ee0ee97e57030.zip |
Fixed bug found by John Blair where trim_string wasn't
correctly trimming trailing multibyte code page strings.
Jeremy.
(This used to be commit dbdbce29f56d03f6abf1ee3d96ca2032e688dcbc)
Diffstat (limited to 'source3/lib/util.c')
-rw-r--r-- | source3/lib/util.c | 96 |
1 files changed, 89 insertions, 7 deletions
diff --git a/source3/lib/util.c b/source3/lib/util.c index e5486e6159..58106acd46 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -1117,8 +1117,28 @@ char *skip_string(char *buf,int n) } /******************************************************************* + Count the number of characters in a string. Normally this will + be the same as the number of bytes in a string for single byte strings, + but will be different for multibyte. + 16.oct.98, jdblair@cobaltnet.com. +********************************************************************/ + +size_t str_charnum(char *s) +{ + size_t len = 0; + + while (*s != '\0') { + int skip = skip_multibyte_char(*s); + s += (skip ? skip : 1); + len++; + } + return len; +} + +/******************************************************************* trim the specified elements off the front and back of a string ********************************************************************/ + BOOL trim_string(char *s,char *front,char *back) { BOOL ret = False; @@ -1138,14 +1158,76 @@ BOOL trim_string(char *s,char *front,char *back) } } - s_len = strlen(s); - while (back_len && s_len >= back_len && - (strncmp(s + s_len - back_len, back, back_len)==0)) + /* + * We split out the multibyte code page + * case here for speed purposes. Under a + * multibyte code page we need to walk the + * string forwards only and multiple times. + * Thanks to John Blair for finding this + * one. JRA. + */ + + if(back_len) { - ret = True; - s[s_len - back_len] = 0; - s_len = strlen(s); - } + if(!is_multibyte_codepage()) + { + s_len = strlen(s); + while ((s_len >= back_len) && + (strncmp(s + s_len - back_len, back, back_len)==0)) + { + ret = True; + s[s_len - back_len] = '\0'; + s_len = strlen(s); + } + } + else + { + + /* + * Multibyte code page case. + * Keep going through the string, trying + * to match the 'back' string with the end + * of the string. If we get a match, truncate + * 'back' off the end of the string and + * go through the string again from the + * start. Keep doing this until we have + * gone through the string with no match + * at the string end. + */ + + size_t mb_back_len = str_charnum(back); + size_t mb_s_len = str_charnum(s); + + while(mb_s_len >= mb_back_len) + { + size_t charcount = 0; + char *mbp = s; + + while(charcount < (mb_s_len - mb_back_len)) + { + size_t skip = skip_multibyte_char(*mbp); + mbp += (skip ? skip : 1); + charcount++; + } + + /* + * mbp now points at mb_back_len multibyte + * characters from the end of s. + */ + + if(strcmp(mbp, back) == 0) + { + ret = True; + *mbp = '\0'; + mb_s_len = str_charnum(s); + mbp = s; + } + else + break; + } /* end while mb_s_len... */ + } /* end else .. */ + } /* end if back_len .. */ + return(ret); } |