Merge in the developer string options from HEAD. We need to ensure 3.0
authorJeremy Allison <jra@samba.org>
Tue, 18 Mar 2003 01:48:11 +0000 (01:48 +0000)
committerJeremy Allison <jra@samba.org>
Tue, 18 Mar 2003 01:48:11 +0000 (01:48 +0000)
is as stable as possible in the string department and some pain now
will help later :-).
Jeremy.
(This used to be commit 86e3eddac698d90f4666b8492b4603a4efbbd67b)

source3/include/safe_string.h
source3/lib/charcnv.c
source3/lib/util.c
source3/lib/util_str.c
source3/libsmb/clistr.c

index 95cf23df8377d4f73f6dbcdd07d53f8d6001e81b..ad7b4139a3075817e638696f1f466ecb26d9e649 100644 (file)
 
 #endif /* !_SPLINT_ */
 
 
 #endif /* !_SPLINT_ */
 
+/* We need a number of different prototypes for our 
+   non-existant fuctions */
 char * __unsafe_string_function_usage_here__(void);
 
 char * __unsafe_string_function_usage_here__(void);
 
-#if 0 && defined __GNUC__ && __GNUC__ >= 2 && defined __OPTIMIZE__
+size_t __unsafe_string_function_usage_here_size_t__(void);
 
 
-#define pstrcpy(d,s) ((sizeof(d) != sizeof(pstring) && sizeof(d) != sizeof(char *)) ? __unsafe_string_function_usage_here__() : safe_strcpy((d), (s),sizeof(pstring)-1))
-#define pstrcat(d,s) ((sizeof(d) != sizeof(pstring) && sizeof(d) != sizeof(char *)) ? __unsafe_string_function_usage_here__() : safe_strcat((d), (s),sizeof(pstring)-1))
-#define fstrcpy(d,s) ((sizeof(d) != sizeof(fstring) && sizeof(d) != sizeof(char *)) ? __unsafe_string_function_usage_here__() : safe_strcpy((d),(s),sizeof(fstring)-1))
-#define fstrcat(d,s) ((sizeof(d) != sizeof(fstring) && sizeof(d) != sizeof(char *)) ? __unsafe_string_function_usage_here__() : safe_strcat((d),(s),sizeof(fstring)-1))
+size_t __unsafe_string_function_usage_here_char__(void);
 
 
-#define fstrterminate(d) ((sizeof(d) != sizeof(fstring) && sizeof(d) != sizeof(char *)) ? __unsafe_string_function_usage_here__() : (((d)[sizeof(fstring)-1]) = '\0'))
-#define pstrterminate(d) ((sizeof(d) != sizeof(pstring) && sizeof(d) != sizeof(char *)) ? __unsafe_string_function_usage_here__() : (((d)[sizeof(pstring)-1]) = '\0'))
+#ifdef HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS
 
 
-#define wpstrcpy(d,s) ((sizeof(d) != sizeof(wpstring) && sizeof(d) != sizeof(smb_ucs2_t *)) ? __unsafe_string_function_usage_here__() : safe_strcpy_w((d),(s),sizeof(wpstring)))
-#define wpstrcat(d,s) ((sizeof(d) != sizeof(wpstring) && sizeof(d) != sizeof(smb_ucs2_t *)) ? __unsafe_string_function_usage_here__() : safe_strcat_w((d),(s),sizeof(wpstring)))
-#define wfstrcpy(d,s) ((sizeof(d) != sizeof(wfstring) && sizeof(d) != sizeof(smb_ucs2_t *)) ? __unsafe_string_function_usage_here__() : safe_strcpy_w((d),(s),sizeof(wfstring)))
-#define wfstrcat(d,s) ((sizeof(d) != sizeof(wfstring) && sizeof(d) != sizeof(smb_ucs2_t *)) ? __unsafe_string_function_usage_here__() : safe_strcat_w((d),(s),sizeof(wfstring)))
+/* if the compiler will optimize out function calls, then use this to tell if we are 
+   have the correct types (this works only where sizeof() returns the size of the buffer, not
+   the size of the pointer). */
 
 
-#else
+#define CHECK_STRING_SIZE(d, len) (sizeof(d) != (len) && sizeof(d) != sizeof(char *))
 
 
-#define pstrcpy(d,s) safe_strcpy((d), (s),sizeof(pstring)-1)
-#define pstrcat(d,s) safe_strcat((d), (s),sizeof(pstring)-1)
-#define fstrcpy(d,s) safe_strcpy((d),(s),sizeof(fstring)-1)
-#define fstrcat(d,s) safe_strcat((d),(s),sizeof(fstring)-1)
+#define fstrterminate(d) (CHECK_STRING_SIZE(d, sizeof(fstring)) \
+    ? __unsafe_string_function_usage_here_char__() \
+    : (((d)[sizeof(fstring)-1]) = '\0'))
+#define pstrterminate(d) (CHECK_STRING_SIZE(d, sizeof(pstring)) \
+    ? __unsafe_string_function_usage_here_char__() \
+    : (((d)[sizeof(pstring)-1]) = '\0'))
+
+#define wpstrcpy(d,s) ((sizeof(d) != sizeof(wpstring) && sizeof(d) != sizeof(smb_ucs2_t *)) \
+    ? __unsafe_string_function_usage_here__() \
+    : safe_strcpy_w((d),(s),sizeof(wpstring)))
+#define wpstrcat(d,s) ((sizeof(d) != sizeof(wpstring) && sizeof(d) != sizeof(smb_ucs2_t *)) \
+    ? __unsafe_string_function_usage_here__() \
+    : safe_strcat_w((d),(s),sizeof(wpstring)))
+#define wfstrcpy(d,s) ((sizeof(d) != sizeof(wfstring) && sizeof(d) != sizeof(smb_ucs2_t *)) \
+    ? __unsafe_string_function_usage_here__() \
+    : safe_strcpy_w((d),(s),sizeof(wfstring)))
+#define wfstrcat(d,s) ((sizeof(d) != sizeof(wfstring) && sizeof(d) != sizeof(smb_ucs2_t *)) \
+    ? __unsafe_string_function_usage_here__() \
+    : safe_strcat_w((d),(s),sizeof(wfstring)))
+
+#define push_pstring_base(dest, src, pstring_base) \
+    (CHECK_STRING_SIZE(pstring_base, sizeof(pstring)) \
+    ? __unsafe_string_function_usage_here_size_t__() \
+    : push_ascii(dest, src, sizeof(pstring)-PTR_DIFF(dest,pstring_base)-1, STR_TERMINATE))
+
+#else /* HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS */
 
 #define fstrterminate(d) (((d)[sizeof(fstring)-1]) = '\0')
 #define pstrterminate(d) (((d)[sizeof(pstring)-1]) = '\0')
 
 #define fstrterminate(d) (((d)[sizeof(fstring)-1]) = '\0')
 #define pstrterminate(d) (((d)[sizeof(pstring)-1]) = '\0')
@@ -80,12 +99,10 @@ char * __unsafe_string_function_usage_here__(void);
 #define wfstrcpy(d,s) safe_strcpy_w((d),(s),sizeof(wfstring))
 #define wfstrcat(d,s) safe_strcat_w((d),(s),sizeof(wfstring))
 
 #define wfstrcpy(d,s) safe_strcpy_w((d),(s),sizeof(wfstring))
 #define wfstrcat(d,s) safe_strcat_w((d),(s),sizeof(wfstring))
 
-#endif
+#define push_pstring_base(dest, src, pstring_base) \
+    push_ascii(dest, src, sizeof(pstring)-PTR_DIFF(dest,pstring_base)-1, STR_TERMINATE)
 
 
-/* replace some string functions with multi-byte
-   versions */
-#define strlower(s) strlower_m(s)
-#define strupper(s) strupper_m(s)
+#endif /* HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS */
 
 /* the addition of the DEVELOPER checks in safe_strcpy means we must
  * update a lot of code. To make this a little easier here are some
 
 /* the addition of the DEVELOPER checks in safe_strcpy means we must
  * update a lot of code. To make this a little easier here are some
@@ -93,8 +110,109 @@ char * __unsafe_string_function_usage_here__(void);
 #define pstrcpy_base(dest, src, pstring_base) \
     safe_strcpy(dest, src, sizeof(pstring)-PTR_DIFF(dest,pstring_base)-1)
 
 #define pstrcpy_base(dest, src, pstring_base) \
     safe_strcpy(dest, src, sizeof(pstring)-PTR_DIFF(dest,pstring_base)-1)
 
-#define push_pstring_base(dest, src, pstring_base) \
-    push_ascii(dest, src, sizeof(pstring)-PTR_DIFF(dest,pstring_base)-1, STR_TERMINATE)
+#define safe_strcpy_base(dest, src, base, size) \
+    safe_strcpy(dest, src, size-PTR_DIFF(dest,base)-1)
+
+/* String copy functions - macro hell below adds 'type checking' (limited, but the best we can
+   do in C) and may tag with function name/number to record the last 'clobber region' on
+   that string */
+
+#define pstrcpy(d,s) safe_strcpy((d), (s),sizeof(pstring)-1)
+#define pstrcat(d,s) safe_strcat((d), (s),sizeof(pstring)-1)
+#define fstrcpy(d,s) safe_strcpy((d),(s),sizeof(fstring)-1)
+#define fstrcat(d,s) safe_strcat((d),(s),sizeof(fstring)-1)
+
+/* the addition of the DEVELOPER checks in safe_strcpy means we must
+ * update a lot of code. To make this a little easier here are some
+ * functions that provide the lengths with less pain */
+#define pstrcpy_base(dest, src, pstring_base) \
+    safe_strcpy(dest, src, sizeof(pstring)-PTR_DIFF(dest,pstring_base)-1)
+
+
+/* inside the _fn varients of these is a call to 'clobber_region' - which might
+   destory the stack on a buggy function.  Help the debugging process by putting
+   the function and line it was last called from into a static buffer
+
+   But only for developers */
+
+#ifdef DEVELOPER
+#define overmalloc_safe_strcpy(dest,src,maxlength)     safe_strcpy_fn(__FUNCTION__,__LINE__,dest,src,maxlength)
+#define safe_strcpy(dest,src,maxlength)        safe_strcpy_fn2(__FUNCTION__,__LINE__,dest,src,maxlength)
+#define safe_strcat(dest,src,maxlength)        safe_strcat_fn2(__FUNCTION__,__LINE__,dest,src,maxlength)
+#define push_string(base_ptr, dest, src, dest_len, flags) push_string_fn2(__FUNCTION__, __LINE__, base_ptr, dest, src, dest_len, flags)
+#define pull_string(base_ptr, dest, src, dest_len, src_len, flags) pull_string_fn2(__FUNCTION__, __LINE__, base_ptr, dest, src, dest_len, src_len, flags)
+#define clistr_push(cli, dest, src, dest_len, flags) clistr_push_fn2(__FUNCTION__, __LINE__, cli, dest, src, dest_len, flags)
+#define clistr_pull(cli, dest, src, dest_len, src_len, flags) clistr_pull_fn2(__FUNCTION__, __LINE__, cli, dest, src, dest_len, src_len, flags)
+
+#define alpha_strcpy(dest,src,other_safe_chars,maxlength) alpha_strcpy_fn(__FUNCTION__,__LINE__,dest,src,other_safe_chars,maxlength)
+#define StrnCpy(dest,src,n)            StrnCpy_fn(__FUNCTION__,__LINE__,dest,src,n)
+
+#else
+
+#define overmalloc_safe_strcpy(dest,src,maxlength)     safe_strcpy_fn(NULL,0,dest,src,maxlength)
+#define safe_strcpy(dest,src,maxlength)        safe_strcpy_fn2(NULL,0,dest,src,maxlength)
+#define safe_strcat(dest,src,maxlength)        safe_strcat_fn2(NULL,0,dest,src,maxlength)
+#define push_string(base_ptr, dest, src, dest_len, flags) push_string_fn2(NULL, 0, base_ptr, dest, src, dest_len, flags)
+#define pull_string(base_ptr, dest, src, dest_len, src_len, flags) pull_string_fn2(NULL, 0, base_ptr, dest, src, dest_len, src_len, flags)
+#define clistr_push(cli, dest, src, dest_len, flags) clistr_push_fn2(NULL, 0, cli, dest, src, dest_len, flags)
+#define clistr_pull(cli, dest, src, dest_len, src_len, flags) clistr_pull_fn2(NULL, 0, cli, dest, src, dest_len, src_len, flags)
+
+#define alpha_strcpy(dest,src,other_safe_chars,maxlength) alpha_strcpy_fn(NULL,0,dest,src,other_safe_chars,maxlength)
+#define StrnCpy(dest,src,n)            StrnCpy_fn(NULL,0,dest,src,n)
+#endif /* DEVELOPER */
+
+
+#ifdef HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS
+
+/* if the compiler will optimize out function calls, then use this to tell if we are 
+   have the correct types (this works only where sizeof() returns the size of the buffer, not
+   the size of the pointer). */
+
+#define safe_strcpy_fn2(fn_name, fn_line, d, s, max_len) \
+    (CHECK_STRING_SIZE(d, max_len+1) \
+    ? __unsafe_string_function_usage_here__() \
+    : safe_strcpy_fn(fn_name, fn_line, (d), (s), (max_len)))
+
+#define safe_strcat_fn2(fn_name, fn_line, d, s, max_len) \
+    (CHECK_STRING_SIZE(d, max_len+1) \
+    ? __unsafe_string_function_usage_here__() \
+    : safe_strcat_fn(fn_name, fn_line, (d), (s), (max_len)))
+
+#define push_string_fn2(fn_name, fn_line, base_ptr, dest, src, dest_len, flags) \
+    (CHECK_STRING_SIZE(dest, dest_len) \
+    ? __unsafe_string_function_usage_here_size_t__() \
+    : push_string_fn(fn_name, fn_line, base_ptr, dest, src, dest_len, flags))
+
+#define pull_string_fn2(fn_name, fn_line, base_ptr, dest, src, dest_len, src_len, flags) \
+    (CHECK_STRING_SIZE(dest, dest_len) \
+    ? __unsafe_string_function_usage_here_size_t__() \
+    : pull_string_fn(fn_name, fn_line, base_ptr, dest, src, dest_len, src_len, flags))
+
+#define clistr_push_fn2(fn_name, fn_line, cli, dest, src, dest_len, flags) \
+    (CHECK_STRING_SIZE(dest, dest_len) \
+    ? __unsafe_string_function_usage_here_size_t__() \
+    : clistr_push_fn(fn_name, fn_line, cli, dest, src, dest_len, flags))
+
+#define clistr_pull_fn2(fn_name, fn_line, cli, dest, src, dest_len, srclen, flags) \
+    (CHECK_STRING_SIZE(dest, dest_len) \
+    ? __unsafe_string_function_usage_here_size_t__() \
+    : clistr_pull_fn(fn_name, fn_line, cli, dest, src, dest_len, srclen, flags))
+
+#else
+
+#define safe_strcpy_fn2 safe_strcpy_fn
+#define safe_strcat_fn2 safe_strcat_fn
+#define push_string_fn2 push_string_fn
+#define pull_string_fn2 pull_string_fn
+#define clistr_push_fn2 clistr_push_fn
+#define clistr_pull_fn2 clistr_pull_fn
+
+#endif
+
+/* replace some string functions with multi-byte
+   versions */
+#define strlower(s) strlower_m(s)
+#define strupper(s) strupper_m(s)
 
 #define safe_strcpy_base(dest, src, base, size) \
     safe_strcpy(dest, src, size-PTR_DIFF(dest,base)-1)
 
 #define safe_strcpy_base(dest, src, base, size) \
     safe_strcpy(dest, src, size-PTR_DIFF(dest,base)-1)
index a8df003f8bca63d030466b42cce2792bd5af3924..fa646573d89bffb6047986bb4835db90c274685c 100644 (file)
@@ -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.
  **/
 
  * @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;
                                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.
  **/
  *
  * @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;
                                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;
 {
        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);
 }
 
        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.
  *
 /**
  * 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.
 **/
 
  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;
 {
        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);
 }
 
        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
  *
 /**
  * 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);   
 }
 
        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
  *
 /**
  * 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.
 **/
 
  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)))) {
        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.
 **/
 
  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)))) {
        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;
 }
 
        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.
 /**
  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;
 }
 
                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.
 /**
  Convert from dos to ucs2 charset and return the
  allocated and converted string or NULL if an error occurred.
index bdf67a515aed8b7cd596796feeed952776e6a4f1..421631033599f5bcece81d69e7278b0f419cc427 100644 (file)
@@ -1398,9 +1398,23 @@ gid_t nametogid(const char *name)
 
 void smb_panic(const char *why)
 {
 
 void smb_panic(const char *why)
 {
-       char *cmd = lp_panic_action();
+       char *cmd;
        int result;
 
        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);
        if (cmd && *cmd) {
                DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
                result = system(cmd);
index 070c59c1b2e17e9e5d5dc3e21f34bbc287fa6c91..7643c2807ea370a4e3c2b185b1e2ccb6b72a878a 100644 (file)
 
 #include "includes.h"
 
 
 #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.
 /**
  * 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!
 **/
 
 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)
 {
 
 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.
 **/
 
 /**
  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;
 
 {
        size_t len;
 
@@ -444,13 +450,7 @@ char *safe_strcpy(char *dest,const char *src, size_t maxlength)
                return NULL;
        }
 
                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;
 
        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.
 **/
  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;
 
 {
        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);
 
        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));
        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;
        }
                dest[maxlength] = 0;
                return NULL;
        }
-       
+
        memcpy(&dest[dest_len], src, src_len);
        dest[dest_len + src_len] = 0;
        return dest;
        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 !
 **/
  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;
 
 {
        size_t len, i;
 
+       clobber_region(fn, line, dest, maxlength);
+
        if (!dest) {
                DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
                return NULL;
        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.
 **/
  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;
 {
        char *d = dest;
+
+       clobber_region(fn, line, dest, n+1);
+
        if (!dest)
                return(NULL);
        if (!dest)
                return(NULL);
+       
        if (!src) {
                *dest = 0;
                return(dest);
        if (!src) {
                *dest = 0;
                return(dest);
@@ -566,16 +571,19 @@ char *StrnCpy(char *dest,const char *src,size_t n)
        return(dest);
 }
 
        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).
 **/
 
 /**
  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;
 
 {
        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));
        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;
 }
 
        return p;
 }
+#endif
 
 /**
  Routine to get hex characters and turn them into a 16 byte array.
 
 /**
  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!
 **/
 
  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;
                                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);
 }
 
        return all_string_sub_w(s, p, i);
 }
 
+#if 0
 /**
  Splits out the front and back at a separator.
 **/
 
 /**
  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);
 
 {
        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;
        }
 }
                        back[0] = 0;
        }
 }
+#endif
 
 /**
  Write an octal as a string.
 
 /**
  Write an octal as a string.
@@ -998,7 +1009,7 @@ const char *octal_string(int i)
  Truncate a string at a specified length.
 **/
 
  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;
 {
        if (s && strlen(s) > length)
                s[length] = 0;
@@ -1157,11 +1168,12 @@ char *binary_string(char *buf, int len)
        return ret;
 }
 
        return ret;
 }
 
+#if 0
 /**
  Just a typesafety wrapper for snprintf into a fstring.
 **/
 
 /**
  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;
 {
        va_list ap;
        int ret;
@@ -1171,6 +1183,7 @@ char *binary_string(char *buf, int len)
        va_end(ap);
        return ret;
 }
        va_end(ap);
        return ret;
 }
+#endif
 
 #ifndef HAVE_STRNDUP
 /**
 
 #ifndef HAVE_STRNDUP
 /**
@@ -1642,12 +1655,3 @@ char * base64_encode_data_blob(DATA_BLOB data)
     return result;
 }
 
     return result;
 }
 
-#ifdef VALGRIND
-size_t valgrind_strlen(const char *s)
-{
-       size_t count;
-       for(count = 0; *s++; count++)
-               ;
-       return count;
-}
-#endif
index 3c9964368edea37899ba507e3360c268961ba5fc..97a3fa6cc99975e9e98d545cde0ea7f613500a05 100644 (file)
 
 #include "includes.h"
 
 
 #include "includes.h"
 
-int clistr_push(struct cli_state *cli, void *dest, const char *src, int dest_len, int flags)
+size_t clistr_push_fn(const char *function, unsigned int line, 
+                  struct cli_state *cli, void *dest, 
+                  const char *src, int dest_len, int flags)
 {
 {
-       return push_string(cli->outbuf, dest, src, dest_len, flags);
+       size_t buf_used = PTR_DIFF(dest, cli->outbuf);
+       if (dest_len == -1) {
+               if (((ptrdiff_t)dest < (ptrdiff_t)cli->outbuf) || (buf_used > cli->bufsize)) {
+                       DEBUG(0, ("Pushing string of 'unlimited' length into non-SMB buffer!\n"));
+                       return push_string_fn(function, line, cli->outbuf, dest, src, -1, flags);
+               }
+               return push_string_fn(function, line, cli->outbuf, dest, src, cli->bufsize - buf_used, flags);
+       }
+       
+       /* 'normal' push into size-specified buffer */
+       return push_string_fn(function, line, cli->outbuf, dest, src, dest_len, flags);
 }
 
 }
 
-int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len, int src_len, 
-               int flags)
+size_t clistr_pull_fn(const char *function, unsigned int line, 
+                  struct cli_state *cli, char *dest, const void *src, 
+                  int dest_len, int src_len, 
+                  int flags)
 {
 {
-       return pull_string(cli->inbuf, dest, src, dest_len, src_len, flags);
+       return pull_string_fn(function, line, cli->inbuf, dest, src, dest_len, src_len, flags);
 }
 
 
 }
 
 
-int clistr_align_out(struct cli_state *cli, const void *p, int flags)
+size_t clistr_align_out(struct cli_state *cli, const void *p, int flags)
 {
        return align_string(cli->outbuf, p, flags);
 }
 
 {
        return align_string(cli->outbuf, p, flags);
 }
 
-int clistr_align_in(struct cli_state *cli, const void *p, int flags)
+size_t clistr_align_in(struct cli_state *cli, const void *p, int flags)
 {
        return align_string(cli->inbuf, p, flags);
 }
 {
        return align_string(cli->inbuf, p, flags);
 }