From d332200c254b4bbf27461a37f9655bf42faa2b3a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Mar 2003 01:48:11 +0000 Subject: Merge in the developer string options from HEAD. We need to ensure 3.0 is as stable as possible in the string department and some pain now will help later :-). Jeremy. (This used to be commit 86e3eddac698d90f4666b8492b4603a4efbbd67b) --- source3/lib/charcnv.c | 115 ++++++------------------------------------------- source3/lib/util.c | 16 ++++++- source3/lib/util_str.c | 98 +++++++++++++++++++++-------------------- 3 files changed, 78 insertions(+), 151 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index a8df003f8b..fa646573d8 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -186,7 +186,7 @@ size_t convert_string(charset_t from, charset_t to, * @returns Size in bytes of the converted string; or -1 in case of error. **/ -size_t convert_string_allocate(charset_t from, charset_t to, +static size_t convert_string_allocate(charset_t from, charset_t to, void const *src, size_t srclen, void **dest) { size_t i_len, o_len, destlen; @@ -265,7 +265,7 @@ convert: * * @returns Size in bytes of the converted string; or -1 in case of error. **/ -size_t convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to, +static size_t convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to, void const *src, size_t srclen, void **dest) { void *alloced_string; @@ -303,7 +303,7 @@ size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen) } -size_t ucs2_align(const void *base_ptr, const void *p, int flags) +static size_t ucs2_align(const void *base_ptr, const void *p, int flags) { if (flags & (STR_NOALIGN|STR_ASCII)) return 0; @@ -356,11 +356,6 @@ size_t push_ascii_pstring(void *dest, const char *src) return push_ascii(dest, src, sizeof(pstring), STR_TERMINATE); } -size_t push_pstring(void *dest, const char *src) -{ - return push_ascii(dest, src, sizeof(pstring), STR_TERMINATE); -} - /** * Copy a string from a dos codepage source to a unix char* destination. * @@ -507,7 +502,7 @@ size_t push_ucs2_allocate(smb_ucs2_t **dest, const char *src) is -1 then no maxiumum is used. **/ -size_t push_utf8(void *dest, const char *src, size_t dest_len, int flags) +static size_t push_utf8(void *dest, const char *src, size_t dest_len, int flags) { size_t src_len = strlen(src); pstring tmpbuf; @@ -533,11 +528,6 @@ size_t push_utf8_fstring(void *dest, const char *src) return push_utf8(dest, src, sizeof(fstring), STR_TERMINATE); } -size_t push_utf8_pstring(void *dest, const char *src) -{ - return push_utf8(dest, src, sizeof(pstring), STR_TERMINATE); -} - /** * Copy a string from a unix char* src to a UTF-8 destination, allocating a buffer using talloc * @@ -656,51 +646,6 @@ size_t pull_ucs2_allocate(void **dest, const smb_ucs2_t *src) return convert_string_allocate(CH_UCS2, CH_UNIX, src, src_len, dest); } -/** - Copy a string from a utf-8 source to a unix char* destination. - Flags can have: - STR_TERMINATE means the string in src is null terminated. - if STR_TERMINATE is set then src_len is ignored. - src_len is the length of the source area in bytes - Return the number of bytes occupied by the string in src. - The resulting string in "dest" is always null terminated. -**/ - -size_t pull_utf8(char *dest, const void *src, size_t dest_len, size_t src_len, int flags) -{ - size_t ret; - - if (dest_len == (size_t)-1) - dest_len = sizeof(pstring); - - if (flags & STR_TERMINATE) { - if (src_len == (size_t)-1) { - src_len = strlen(src) + 1; - } else { - size_t len = strnlen(src, src_len); - if (len < src_len) - len++; - src_len = len; - } - } - - ret = convert_string(CH_UTF8, CH_UNIX, src, src_len, dest, dest_len); - if (dest_len) - dest[MIN(ret, dest_len-1)] = 0; - - return src_len; -} - -size_t pull_utf8_pstring(char *dest, const void *src) -{ - return pull_utf8(dest, src, sizeof(pstring), -1, STR_TERMINATE); -} - -size_t pull_utf8_fstring(char *dest, const void *src) -{ - return pull_utf8(dest, src, sizeof(fstring), -1, STR_TERMINATE); -} - /** * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer using talloc * @@ -745,8 +690,11 @@ size_t pull_utf8_allocate(void **dest, const char *src) is -1 then no maxiumum is used. **/ -size_t push_string(const void *base_ptr, void *dest, const char *src, size_t dest_len, int flags) +size_t push_string_fn(const char *function, unsigned int line, const void *base_ptr, void *dest, const char *src, size_t dest_len, int flags) { + if (dest_len != (size_t)-1) + clobber_region(function, line, dest, dest_len); + if (!(flags & STR_ASCII) && \ ((flags & STR_UNICODE || \ (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) { @@ -770,8 +718,11 @@ size_t push_string(const void *base_ptr, void *dest, const char *src, size_t des The resulting string in "dest" is always null terminated. **/ -size_t pull_string(const void *base_ptr, char *dest, const void *src, size_t dest_len, size_t src_len, int flags) +size_t pull_string_fn(const char *function, unsigned int line, const void *base_ptr, char *dest, const void *src, size_t dest_len, size_t src_len, int flags) { + if (dest_len != (size_t)-1) + clobber_region(function, line, dest, dest_len); + if (!(flags & STR_ASCII) && \ ((flags & STR_UNICODE || \ (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) { @@ -790,27 +741,6 @@ size_t align_string(const void *base_ptr, const char *p, int flags) return 0; } -/** - Convert from ucs2 to unix charset and return the - allocated and converted string or NULL if an error occurred. - You must provide a zero terminated string. - The returning string will be zero terminated. -**/ - -char *acnv_u2ux(const smb_ucs2_t *src) -{ - size_t slen; - size_t dlen; - void *dest; - - slen = (strlen_w(src) + 1) * sizeof(smb_ucs2_t); - dlen = convert_string_allocate(CH_UCS2, CH_UNIX, src, slen, &dest); - if (dlen == (size_t)-1) - return NULL; - else - return dest; -} - /** Convert from unix to ucs2 charset and return the allocated and converted string or NULL if an error occurred. @@ -832,27 +762,6 @@ smb_ucs2_t *acnv_uxu2(const char *src) return dest; } -/** - Convert from ucs2 to dos charset and return the - allocated and converted string or NULL if an error occurred. - You must provide a zero terminated string. - The returning string will be zero terminated. -**/ - -char *acnv_u2dos(const smb_ucs2_t *src) -{ - size_t slen; - size_t dlen; - void *dest; - - slen = (strlen_w(src) + 1) * sizeof(smb_ucs2_t); - dlen = convert_string_allocate(CH_UCS2, CH_DOS, src, slen, &dest); - if (dlen == (size_t)-1) - return NULL; - else - return dest; -} - /** Convert from dos to ucs2 charset and return the allocated and converted string or NULL if an error occurred. diff --git a/source3/lib/util.c b/source3/lib/util.c index bdf67a515a..4216310335 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -1398,9 +1398,23 @@ gid_t nametogid(const char *name) void smb_panic(const char *why) { - char *cmd = lp_panic_action(); + char *cmd; int result; +#ifdef DEVELOPER + { + extern char *global_clobber_region_function; + extern unsigned int global_clobber_region_line; + + if (global_clobber_region_function) { + DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n", + global_clobber_region_function, + global_clobber_region_line)); + } + } +#endif + + cmd = lp_panic_action(); if (cmd && *cmd) { DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd)); result = system(cmd); diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 070c59c1b2..7643c2807e 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -21,6 +21,11 @@ #include "includes.h" +#ifdef DEVELOPER +const char *global_clobber_region_function; +unsigned int global_clobber_region_line; +#endif + /** * Get the next token from a string, return False if none found. * Handles double-quotes. @@ -73,7 +78,7 @@ parameter so you can pass NULL. This is useful for user interface code but beware the fact that it is not re-entrant! **/ -static char *last_ptr=NULL; +static const char *last_ptr=NULL; BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize) { @@ -410,32 +415,33 @@ size_t count_chars(const char *s,char c) } /** -Return True if a string consists only of one particular character. -**/ - -BOOL str_is_all(const char *s,char c) + * In developer builds, clobber a region of memory. + * + * If we think a string buffer is longer than it really is, this ought + * to make the failure obvious, by segfaulting (if in the heap) or by + * killing the return address (on the stack), or by trapping under a + * memory debugger. + * + * This is meant to catch possible string overflows, even if the + * actual string copied is not big enough to cause an overflow. + **/ +void clobber_region(const char *fn, unsigned int line, char *dest, size_t len) { - smb_ucs2_t *ptr; - - if(s == NULL) - return False; - if(!*s) - return False; - - push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE); - for(ptr=tmpbuf;*ptr;ptr++) - if(*ptr!=UCS2_CHAR(c)) - return False; - - return True; +#ifdef DEVELOPER + /* F1 is odd and 0xf1f1f1f1 shouldn't be a valid pointer */ + memset(dest, 0xF1, len); + global_clobber_region_function = fn; + global_clobber_region_line = line; +#endif } + /** Safe string copy into a known length string. maxlength does not include the terminating zero. **/ -char *safe_strcpy(char *dest,const char *src, size_t maxlength) +char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength) { size_t len; @@ -444,13 +450,7 @@ char *safe_strcpy(char *dest,const char *src, size_t maxlength) return NULL; } -#ifdef DEVELOPER - /* We intentionally write out at the extremity of the destination - * string. If the destination is too short (e.g. pstrcpy into mallocd - * or fstring) then this should cause an error under a memory - * checker. */ - dest[maxlength] = '\0'; -#endif + clobber_region(fn,line,dest, maxlength+1); if (!src) { *dest = 0; @@ -474,8 +474,7 @@ char *safe_strcpy(char *dest,const char *src, size_t maxlength) Safe string cat into a string. maxlength does not include the terminating zero. **/ - -char *safe_strcat(char *dest, const char *src, size_t maxlength) +char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength) { size_t src_len, dest_len; @@ -490,6 +489,8 @@ char *safe_strcat(char *dest, const char *src, size_t maxlength) src_len = strlen(src); dest_len = strlen(dest); + clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len); + if (src_len + dest_len > maxlength) { DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n", (int)(src_len + dest_len - maxlength), src)); @@ -499,7 +500,7 @@ char *safe_strcat(char *dest, const char *src, size_t maxlength) dest[maxlength] = 0; return NULL; } - + memcpy(&dest[dest_len], src, src_len); dest[dest_len + src_len] = 0; return dest; @@ -511,11 +512,12 @@ char *safe_strcat(char *dest, const char *src, size_t maxlength) and replaces with '_'. Deliberately does *NOT* check for multibyte characters. Don't change it ! **/ - -char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, size_t maxlength) +char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength) { size_t len, i; + clobber_region(fn, line, dest, maxlength); + if (!dest) { DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n")); return NULL; @@ -550,12 +552,15 @@ char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, si Like strncpy but always null terminates. Make sure there is room! The variable n should always be one less than the available size. **/ - -char *StrnCpy(char *dest,const char *src,size_t n) +char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n) { char *d = dest; + + clobber_region(fn, line, dest, n+1); + if (!dest) return(NULL); + if (!src) { *dest = 0; return(dest); @@ -566,16 +571,19 @@ char *StrnCpy(char *dest,const char *src,size_t n) return(dest); } +#if 0 /** Like strncpy but copies up to the character marker. always null terminates. returns a pointer to the character marker in the source string (src). **/ -char *strncpyn(char *dest, const char *src, size_t n, char c) +static char *strncpyn(char *dest, const char *src, size_t n, char c) { char *p; size_t str_len; + clobber_region(dest, n+1); + p = strchr_m(src, c); if (p == NULL) { DEBUG(5, ("strncpyn: separator character (%c) not found\n", c)); @@ -588,6 +596,7 @@ char *strncpyn(char *dest, const char *src, size_t n, char c) return p; } +#endif /** Routine to get hex characters and turn them into a 16 byte array. @@ -898,7 +907,7 @@ void all_string_sub(char *s,const char *pattern,const char *insert, size_t len) Use with caution! **/ -smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern, +static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern, const smb_ucs2_t *insert) { smb_ucs2_t *r, *rp; @@ -956,11 +965,12 @@ smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern, return all_string_sub_w(s, p, i); } +#if 0 /** Splits out the front and back at a separator. **/ -void split_at_last_component(char *path, char *front, char sep, char *back) +static void split_at_last_component(char *path, char *front, char sep, char *back) { char *p = strrchr_m(path, sep); @@ -979,6 +989,7 @@ void split_at_last_component(char *path, char *front, char sep, char *back) back[0] = 0; } } +#endif /** Write an octal as a string. @@ -998,7 +1009,7 @@ const char *octal_string(int i) Truncate a string at a specified length. **/ -char *string_truncate(char *s, int length) +char *string_truncate(char *s, unsigned int length) { if (s && strlen(s) > length) s[length] = 0; @@ -1157,11 +1168,12 @@ char *binary_string(char *buf, int len) return ret; } +#if 0 /** Just a typesafety wrapper for snprintf into a fstring. **/ - int fstr_sprintf(fstring s, const char *fmt, ...) +static int fstr_sprintf(fstring s, const char *fmt, ...) { va_list ap; int ret; @@ -1171,6 +1183,7 @@ char *binary_string(char *buf, int len) va_end(ap); return ret; } +#endif #ifndef HAVE_STRNDUP /** @@ -1642,12 +1655,3 @@ char * base64_encode_data_blob(DATA_BLOB data) return result; } -#ifdef VALGRIND -size_t valgrind_strlen(const char *s) -{ - size_t count; - for(count = 0; *s++; count++) - ; - return count; -} -#endif -- cgit