diff options
author | Gerald Carter <jerry@samba.org> | 2007-09-27 22:50:48 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2007-09-27 22:50:48 +0000 |
commit | 1a6570fce8f96fca00f557ecb0d9b14528b1faf9 (patch) | |
tree | fced4d31f98c2f0c876fe3c5e9cf3976b063bea4 /source/lib | |
parent | 39c8e7b8485f7f0e14d79aced523711ea9f4e55e (diff) | |
download | samba-1a6570fce8f96fca00f557ecb0d9b14528b1faf9.tar.gz samba-1a6570fce8f96fca00f557ecb0d9b14528b1faf9.tar.xz samba-1a6570fce8f96fca00f557ecb0d9b14528b1faf9.zip |
r25387: Sync with 3.2.0 svn tree
Diffstat (limited to 'source/lib')
-rw-r--r-- | source/lib/adt_tree.c | 52 | ||||
-rw-r--r-- | source/lib/charcnv.c | 251 | ||||
-rw-r--r-- | source/lib/ctdbd_conn.c | 2 | ||||
-rw-r--r-- | source/lib/events.c | 5 | ||||
-rw-r--r-- | source/lib/fault.c | 8 | ||||
-rw-r--r-- | source/lib/module.c | 47 | ||||
-rw-r--r-- | source/lib/ms_fnmatch.c | 43 | ||||
-rw-r--r-- | source/lib/replace/dlfcn.m4 | 2 | ||||
-rw-r--r-- | source/lib/replace/libreplace.m4 | 12 | ||||
-rw-r--r-- | source/lib/replace/replace.h | 77 | ||||
-rw-r--r-- | source/lib/replace/system/network.h | 8 | ||||
-rw-r--r-- | source/lib/replace/test/testsuite.c | 2 | ||||
-rw-r--r-- | source/lib/smbrun.c | 28 | ||||
-rw-r--r-- | source/lib/system.c | 176 | ||||
-rw-r--r-- | source/lib/talloc/configure.ac | 2 | ||||
-rw-r--r-- | source/lib/talloc/talloc.c | 239 | ||||
-rw-r--r-- | source/lib/talloc/talloc.h | 24 | ||||
-rw-r--r-- | source/lib/talloc/talloc_guide.txt | 19 | ||||
-rw-r--r-- | source/lib/talloc/testsuite.c | 48 | ||||
-rw-r--r-- | source/lib/util.c | 16 | ||||
-rw-r--r-- | source/lib/util_str.c | 241 | ||||
-rw-r--r-- | source/lib/util_unistr.c | 4 |
22 files changed, 794 insertions, 512 deletions
diff --git a/source/lib/adt_tree.c b/source/lib/adt_tree.c index f26f924d61f..cf305d7307e 100644 --- a/source/lib/adt_tree.c +++ b/source/lib/adt_tree.c @@ -278,31 +278,41 @@ done: Recursive routine to print out all children of a TREE_NODE *************************************************************************/ -static void pathtree_print_children( TREE_NODE *node, int debug, const char *path ) +static void pathtree_print_children(TALLOC_CTX *ctx, + TREE_NODE *node, + int debug, + const char *path ) { int i; int num_children; - pstring path2; - + char *path2 = NULL; + if ( !node ) return; - - + if ( node->key ) DEBUG(debug,("%s: [%s] (%s)\n", path ? path : "NULL", node->key, node->data_p ? "data" : "NULL" )); - *path2 = '\0'; - if ( path ) - pstrcpy( path2, path ); - pstrcat( path2, node->key ? node->key : "NULL" ); - pstrcat( path2, "/" ); - - num_children = node->num_children; - for ( i=0; i<num_children; i++ ) - pathtree_print_children( node->children[i], debug, path2 ); - + if ( path ) { + path2 = talloc_strdup(ctx, path); + if (!path2) { + return; + } + } + + path2 = talloc_asprintf(ctx, + "%s%s/", + path ? path : "", + node->key ? node->key : "NULL"); + if (!path2) { + return; + } + num_children = node->num_children; + for ( i=0; i<num_children; i++ ) { + pathtree_print_children(ctx, node->children[i], debug, path2 ); + } } /************************************************************************** @@ -313,21 +323,23 @@ static void pathtree_print_children( TREE_NODE *node, int debug, const char *pat { int i; int num_children = tree->root->num_children; - + if ( tree->root->key ) DEBUG(debug,("ROOT/: [%s] (%s)\n", tree->root->key, tree->root->data_p ? "data" : "NULL" )); - + for ( i=0; i<num_children; i++ ) { - pathtree_print_children( tree->root->children[i], debug, + TALLOC_CTX *ctx = talloc_stackframe(); + pathtree_print_children(ctx, tree->root->children[i], debug, tree->root->key ? tree->root->key : "ROOT/" ); + TALLOC_FREE(ctx); } - + } /************************************************************************** return the data_p for for the node in tree matching the key string - The key string is the full path. We must break it apart and walk + The key string is the full path. We must break it apart and walk the tree *************************************************************************/ diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c index 349fbff8506..b1e3d3bdcfb 100644 --- a/source/lib/charcnv.c +++ b/source/lib/charcnv.c @@ -745,7 +745,7 @@ size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen) size = push_ucs2_allocate(&buffer, src); if (size == (size_t)-1) { - smb_panic("failed to create UCS2 buffer"); + return (size_t)-1; } if (!strupper_w(buffer) && (dest == src)) { free(buffer); @@ -759,49 +759,131 @@ size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen) /** strdup() a unix string to upper case. - Max size is pstring. **/ char *strdup_upper(const char *s) { - pstring out_buffer; + char *out_buffer = SMB_STRDUP(s); const unsigned char *p = (const unsigned char *)s; unsigned char *q = (unsigned char *)out_buffer; + if (!q) { + return NULL; + } + /* this is quite a common operation, so we want it to be fast. We optimise for the ascii case, knowing that all our supported multi-byte character sets are ascii-compatible (ie. they match for the first 128 chars) */ - while (1) { + while (*p) { if (*p & 0x80) break; *q++ = toupper_ascii(*p); - if (!*p) - break; p++; - if (p - ( const unsigned char *)s >= sizeof(pstring)) - break; } if (*p) { /* MB case. */ size_t size; - wpstring buffer; - size = convert_string(CH_UNIX, CH_UTF16LE, s, -1, buffer, sizeof(buffer), True); + smb_ucs2_t *buffer = NULL; + + SAFE_FREE(out_buffer); + size = convert_string_allocate(NULL, + CH_UNIX, + CH_UTF16LE, + s, + strlen(s) + 1, + (void **)(void *)&buffer, + True); if (size == (size_t)-1) { return NULL; } strupper_w(buffer); - size = convert_string(CH_UTF16LE, CH_UNIX, buffer, -1, out_buffer, sizeof(out_buffer), True); + size = convert_string_allocate(NULL, + CH_UTF16LE, + CH_UNIX, + buffer, + size, + (void **)(void *)&out_buffer, + True); + + /* Don't need the intermediate buffer + * anymore. + */ + + TALLOC_FREE(buffer); + if (size == (size_t)-1) { + return NULL; + } + } + + return out_buffer; +} + +/** + talloc_strdup() a unix string to upper case. +**/ + +char *talloc_strdup_upper(TALLOC_CTX *ctx, const char *s) +{ + char *out_buffer = talloc_strdup(ctx,s); + const unsigned char *p = (const unsigned char *)s; + unsigned char *q = (unsigned char *)out_buffer; + + if (!q) { + return NULL; + } + + /* this is quite a common operation, so we want it to be + fast. We optimise for the ascii case, knowing that all our + supported multi-byte character sets are ascii-compatible + (ie. they match for the first 128 chars) */ + + while (*p) { + if (*p & 0x80) + break; + *q++ = toupper_ascii(*p); + p++; + } + + if (*p) { + /* MB case. */ + size_t size; + smb_ucs2_t *ubuf = NULL; + + /* We're not using the ascii buffer above. */ + TALLOC_FREE(out_buffer); + + size = convert_string_talloc(ctx, CH_UNIX, CH_UTF16LE, + s, strlen(s)+1, + (void *)&ubuf, + True); + if (size == (size_t)-1) { + return NULL; + } + + strupper_w(ubuf); + + size = convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, + ubuf, size, + (void *)&out_buffer, + True); + + /* Don't need the intermediate buffer + * anymore. + */ + + TALLOC_FREE(ubuf); + if (size == (size_t)-1) { return NULL; } } - return SMB_STRDUP(out_buffer); + return out_buffer; } size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen) @@ -870,27 +952,40 @@ static size_t ucs2_align(const void *base_ptr, const void *p, int flags) * </dl> * * @param dest_len the maximum length in bytes allowed in the - * destination. If @p dest_len is -1 then no maximum is used. + * destination. **/ size_t push_ascii(void *dest, const char *src, size_t dest_len, int flags) { size_t src_len = strlen(src); - pstring tmpbuf; + char *tmpbuf = NULL; + size_t ret; - /* treat a pstring as "unlimited" length */ - if (dest_len == (size_t)-1) - dest_len = sizeof(pstring); + /* No longer allow a length of -1. */ + if (dest_len == (size_t)-1) { + smb_panic("push_ascii - dest_len == -1"); + } if (flags & STR_UPPER) { - pstrcpy(tmpbuf, src); + tmpbuf = SMB_STRDUP(src); + if (!tmpbuf) { + smb_panic("malloc fail"); + } strupper_m(tmpbuf); src = tmpbuf; } - if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII)) + if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII)) { src_len++; + } - return convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len, True); + ret = convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len, True); + if (ret == (size_t)-1 && + (flags & (STR_TERMINATE | STR_TERMINATE_ASCII)) + && dest_len > 0) { + ((char *)dest)[0] = '\0'; + } + SAFE_FREE(tmpbuf); + return ret; } size_t push_ascii_fstring(void *dest, const char *src) @@ -942,6 +1037,18 @@ size_t push_ascii_nstring(void *dest, const char *src) return dest_len; } +/******************************************************************** + Push and malloc an ascii string. src and dest null terminated. +********************************************************************/ + +size_t push_ascii_allocate(char **dest, const char *src) +{ + size_t src_len = strlen(src)+1; + + *dest = NULL; + return convert_string_allocate(NULL, CH_UNIX, CH_DOS, src, src_len, (void **)dest, True); +} + /** * Copy a string from a dos codepage source to a unix char* destination. * @@ -961,8 +1068,10 @@ size_t pull_ascii(char *dest, const void *src, size_t dest_len, size_t src_len, { size_t ret; - if (dest_len == (size_t)-1) - dest_len = sizeof(pstring); + if (dest_len == (size_t)-1) { + /* No longer allow dest_len of -1. */ + smb_panic("pull_ascii - invalid dest_len of -1"); + } if (flags & STR_TERMINATE) { if (src_len == (size_t)-1) { @@ -1041,7 +1150,11 @@ static size_t pull_ascii_base_talloc(TALLOC_CTX *ctx, } /* Ensure we don't use an insane length from the client. */ if (src_len >= 1024*1024) { - smb_panic("Bad src length in pull_ascii_base_talloc\n"); + char *msg = talloc_asprintf(ctx, + "Bad src length (%u) in " + "pull_ascii_base_talloc", + (unsigned int)src_len); + smb_panic(msg); } } @@ -1054,7 +1167,7 @@ static size_t pull_ascii_base_talloc(TALLOC_CTX *ctx, True); if (dest_len == (size_t)-1) { - return 0; + dest_len = 0; } if (dest_len && dest) { @@ -1102,7 +1215,7 @@ size_t pull_ascii_nstring(char *dest, size_t dest_len, const void *src) * </dl> * * @param dest_len is the maximum length allowed in the - * destination. If dest_len is -1 then no maxiumum is used. + * destination. **/ size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_len, int flags) @@ -1111,9 +1224,10 @@ size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_ size_t src_len; size_t ret; - /* treat a pstring as "unlimited" length */ - if (dest_len == (size_t)-1) - dest_len = sizeof(pstring); + if (dest_len == (size_t)-1) { + /* No longer allow dest_len of -1. */ + smb_panic("push_ucs2 - invalid dest_len of -1"); + } if (flags & STR_TERMINATE) src_len = (size_t)-1; @@ -1133,7 +1247,12 @@ size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_ ret = convert_string(CH_UNIX, CH_UTF16LE, src, src_len, dest, dest_len, True); if (ret == (size_t)-1) { - return 0; + if ((flags & STR_TERMINATE) && + dest && + dest_len) { + *(char *)dest = 0; + } + return len; } len += ret; @@ -1204,23 +1323,32 @@ size_t push_ucs2_allocate(smb_ucs2_t **dest, const char *src) 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 = 0; + size_t ret; + char *tmpbuf = NULL; - /* treat a pstring as "unlimited" length */ - if (dest_len == (size_t)-1) - dest_len = sizeof(pstring); + if (dest_len == (size_t)-1) { + /* No longer allow dest_len of -1. */ + smb_panic("push_utf8 - invalid dest_len of -1"); + } if (flags & STR_UPPER) { - pstrcpy(tmpbuf, src); - strupper_m(tmpbuf); + tmpbuf = strdup_upper(src); + if (!tmpbuf) { + return (size_t)-1; + } src = tmpbuf; + src_len = strlen(src); } - if (flags & STR_TERMINATE) + src_len = strlen(src); + if (flags & STR_TERMINATE) { src_len++; + } - return convert_string(CH_UNIX, CH_UTF8, src, src_len, dest, dest_len, True); + ret = convert_string(CH_UNIX, CH_UTF8, src, src_len, dest, dest_len, True); + SAFE_FREE(tmpbuf); + return ret; } size_t push_utf8_fstring(void *dest, const char *src) @@ -1275,8 +1403,17 @@ size_t pull_ucs2(const void *base_ptr, char *dest, const void *src, size_t dest_ { size_t ret; - if (dest_len == (size_t)-1) - dest_len = sizeof(pstring); + if (dest_len == (size_t)-1) { + /* No longer allow dest_len of -1. */ + smb_panic("pull_ucs2 - invalid dest_len of -1"); + } + + if (!src_len) { + if (dest && dest_len > 0) { + dest[0] = '\0'; + } + return 0; + } if (ucs2_align(base_ptr, src, flags)) { src = (const void *)((const char *)src + 1); @@ -1301,7 +1438,8 @@ size_t pull_ucs2(const void *base_ptr, char *dest, const void *src, size_t dest_ ret = convert_string(CH_UTF16LE, CH_UNIX, src, src_len, dest, dest_len, True); if (ret == (size_t)-1) { - return 0; + ret = 0; + dest_len = 0; } if (src_len == (size_t)-1) @@ -1352,6 +1490,10 @@ static size_t pull_ucs2_base_talloc(TALLOC_CTX *ctx, } #endif + if (!src_len) { + return 0; + } + if (ucs2_align(base_ptr, src, flags)) { src = (const void *)((const char *)src + 1); if (src_len != (size_t)-1) @@ -1386,7 +1528,7 @@ static size_t pull_ucs2_base_talloc(TALLOC_CTX *ctx, (void *)&dest, True); if (dest_len == (size_t)-1) { - return 0; + dest_len = 0; } if (src_len == (size_t)-1) @@ -1395,7 +1537,21 @@ static size_t pull_ucs2_base_talloc(TALLOC_CTX *ctx, if (dest_len) { /* Did we already process the terminating zero ? */ if (dest[dest_len-1] != 0) { - dest[dest_len-1] = 0; + size_t size = talloc_get_size(dest); + /* Have we got space to append the '\0' ? */ + if (size <= dest_len) { + /* No, realloc. */ + dest = TALLOC_REALLOC_ARRAY(ctx, dest, char, + dest_len+1); + if (!dest) { + /* talloc fail. */ + dest_len = (size_t)-1; + return 0; + } + } + /* Yay - space ! */ + dest[dest_len] = '\0'; + dest_len++; } } else if (dest) { dest[0] = 0; @@ -1517,11 +1673,9 @@ size_t push_string_fn(const char *function, unsigned int line, * JRA. */ #if 0 - if (dest_len != (size_t)-1) - clobber_region(function, line, dest, dest_len); + clobber_region(function, line, dest, dest_len); #else - if (dest_len != (size_t)-1) - memset(dest, '\0', dest_len); + memset(dest, '\0', dest_len); #endif #endif @@ -1554,8 +1708,7 @@ size_t pull_string_fn(const char *function, unsigned int line, int flags) { #ifdef DEVELOPER - if (dest_len != (size_t)-1) - clobber_region(function, line, dest, dest_len); + clobber_region(function, line, dest, dest_len); #endif if ((base_ptr == NULL) && ((flags & (STR_ASCII|STR_UNICODE)) == 0)) { diff --git a/source/lib/ctdbd_conn.c b/source/lib/ctdbd_conn.c index f56520b4a36..08ab256accf 100644 --- a/source/lib/ctdbd_conn.c +++ b/source/lib/ctdbd_conn.c @@ -95,7 +95,7 @@ static NTSTATUS get_cluster_vnn(struct ctdbd_connection *conn, uint32 *vnn) int32_t cstatus=-1; NTSTATUS status; status = ctdbd_control(conn, - CTDB_CURRENT_NODE, CTDB_CONTROL_GET_VNN, 0, + CTDB_CURRENT_NODE, CTDB_CONTROL_GET_PNN, 0, tdb_null, NULL, NULL, &cstatus); if (!NT_STATUS_IS_OK(status)) { cluster_fatal("ctdbd_control failed\n"); diff --git a/source/lib/events.c b/source/lib/events.c index e915777217b..befab3f5c00 100644 --- a/source/lib/events.c +++ b/source/lib/events.c @@ -409,10 +409,11 @@ void dump_event_list(struct event_context *event_ctx) evt = timeval_until(&now, &te->when); - DEBUGADD(10,("Timed Event \"%s\" %lx handled in %d seconds\n", + DEBUGADD(10,("Timed Event \"%s\" %lx handled in %d seconds (at %s)\n", te->event_name, (unsigned long)te, - (int)evt.tv_sec)); + (int)evt.tv_sec, + http_timestring(te->when.tv_sec))); } for (fe = event_ctx->fd_events; fe; fe = fe->next) { diff --git a/source/lib/fault.c b/source/lib/fault.c index 3ddb88edc75..6ab1a079006 100644 --- a/source/lib/fault.c +++ b/source/lib/fault.c @@ -150,6 +150,14 @@ void dump_core_setup(const char *progname) void dump_core(void) { + static bool called; + + if (called) { + DEBUG(0, ("dump_core() called recursive\n")); + exit(1); + } + called = true; + /* Note that even if core dumping has been disabled, we still set up * the core path. This is to handle the case where core dumping is * turned on in smb.conf and the relevant daemon is not restarted. diff --git a/source/lib/module.c b/source/lib/module.c index 1bf305ea3f7..57b4c38edc9 100644 --- a/source/lib/module.c +++ b/source/lib/module.c @@ -76,7 +76,7 @@ NTSTATUS smb_load_module(const char *module_name) return do_smb_load_module(module_name, False); } -/* Load all modules in list and return number of +/* Load all modules in list and return number of * modules that has been successfully loaded */ int smb_load_modules(const char **modules) { @@ -96,28 +96,41 @@ int smb_load_modules(const char **modules) NTSTATUS smb_probe_module(const char *subsystem, const char *module) { - pstring full_path; - + char *full_path = NULL; + TALLOC_CTX *ctx = talloc_stackframe(); + NTSTATUS status; + /* Check for absolute path */ - /* if we make any 'samba multibyte string' - calls here, we break + /* if we make any 'samba multibyte string' + calls here, we break for loading string modules */ DEBUG(5, ("Probing module '%s'\n", module)); - if (module[0] == '/') - return do_smb_load_module(module, True); - - pstrcpy(full_path, lib_path(subsystem)); - pstrcat(full_path, "/"); - pstrcat(full_path, module); - pstrcat(full_path, "."); - pstrcat(full_path, shlib_ext()); - - DEBUG(5, ("Probing module '%s': Trying to load from %s\n", module, full_path)); - - return do_smb_load_module(full_path, True); + if (module[0] == '/') { + status = do_smb_load_module(module, True); + TALLOC_FREE(ctx); + return status; + } + + full_path = talloc_asprintf(ctx, + "%s/%s.%s", + lib_path(subsystem), + module, + shlib_ext()); + if (!full_path) { + TALLOC_FREE(ctx); + return NT_STATUS_NO_MEMORY; + } + + DEBUG(5, ("Probing module '%s': Trying to load from %s\n", + module, full_path)); + + status = do_smb_load_module(full_path, True); + + TALLOC_FREE(ctx); + return status; } #else /* HAVE_DLOPEN */ diff --git a/source/lib/ms_fnmatch.c b/source/lib/ms_fnmatch.c index bdfaca143cf..9dc942c5f2e 100644 --- a/source/lib/ms_fnmatch.c +++ b/source/lib/ms_fnmatch.c @@ -1,4 +1,4 @@ -/* +/* Unix SMB/CIFS implementation. filename matching routine Copyright (C) Andrew Tridgell 1992-2004 @@ -7,21 +7,21 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. + along with this program. If not, see <http://www.gnu.org/licenses/>. */ /* This module was originally based on fnmatch.c copyright by the Free Software Foundation. It bears little (if any) resemblence to that code now -*/ +*/ #include "includes.h" @@ -53,7 +53,7 @@ struct max_n { an optimisation only. The ldot pointer is NULL if the string does not contain a '.', otherwise it points at the last dot in 'n'. */ -static int ms_fnmatch_core(const smb_ucs2_t *p, const smb_ucs2_t *n, +static int ms_fnmatch_core(const smb_ucs2_t *p, const smb_ucs2_t *n, struct max_n *max_n, const smb_ucs2_t *ldot, BOOL is_case_sensitive) { @@ -137,22 +137,23 @@ static int ms_fnmatch_core(const smb_ucs2_t *p, const smb_ucs2_t *n, break; } } - + if (! *n) { return 0; } - + return -1; } int ms_fnmatch(const char *pattern, const char *string, BOOL translate_pattern, BOOL is_case_sensitive) { - wpstring p, s; + smb_ucs2_t *p = NULL; + smb_ucs2_t *s = NULL; int ret, count, i; struct max_n *max_n = NULL; - if (strcmp(string, "..") == 0) { + if (ISDOTDOT(string)) { string = "."; } @@ -166,15 +167,12 @@ int ms_fnmatch(const char *pattern, const char *string, BOOL translate_pattern, } } - if (push_ucs2(NULL, p, pattern, sizeof(p), STR_TERMINATE) == (size_t)-1) { - /* Not quite the right answer, but finding the right one - under this failure case is expensive, and it's pretty close */ + if (push_ucs2_allocate(&p, pattern) == (size_t)-1) { return -1; } - if (push_ucs2(NULL, s, string, sizeof(s), STR_TERMINATE) == (size_t)-1) { - /* Not quite the right answer, but finding the right one - under this failure case is expensive, and it's pretty close */ + if (push_ucs2_allocate(&s, string) == (size_t)-1) { + SAFE_FREE(p); return -1; } @@ -187,8 +185,8 @@ int ms_fnmatch(const char *pattern, const char *string, BOOL translate_pattern, for (i=0;p[i];i++) { if (p[i] == UCS2_CHAR('?')) { p[i] = UCS2_CHAR('>'); - } else if (p[i] == UCS2_CHAR('.') && - (p[i+1] == UCS2_CHAR('?') || + } else if (p[i] == UCS2_CHAR('.') && + (p[i+1] == UCS2_CHAR('?') || p[i+1] == UCS2_CHAR('*') || p[i+1] == 0)) { p[i] = UCS2_CHAR('"'); @@ -205,16 +203,17 @@ int ms_fnmatch(const char *pattern, const char *string, BOOL translate_pattern, if (count != 0) { max_n = SMB_CALLOC_ARRAY(struct max_n, count); if (!max_n) { + SAFE_FREE(p); + SAFE_FREE(s); return -1; } } ret = ms_fnmatch_core(p, s, max_n, strrchr_w(s, UCS2_CHAR('.')), is_case_sensitive); - if (max_n) { - free(max_n); - } - + SAFE_FREE(max_n); + SAFE_FREE(p); + SAFE_FREE(s); return ret; } diff --git a/source/lib/replace/dlfcn.m4 b/source/lib/replace/dlfcn.m4 index a1b57d10ec4..c5b7597d7a3 100644 --- a/source/lib/replace/dlfcn.m4 +++ b/source/lib/replace/dlfcn.m4 @@ -12,7 +12,7 @@ AC_VERIFY_C_PROTOTYPE([void *dlopen(const char* filename, unsigned int flags)], [ return 0; ],[ - AC_DEFINE(DLOPEN_TAKES_UNSIGNED_FLAGS, 1, [Whether dlopen takes unsinged int flags]) + AC_DEFINE(DLOPEN_TAKES_UNSIGNED_FLAGS, 1, [Whether dlopen takes unsigned int flags]) ],[],[ #include <dlfcn.h> ]) diff --git a/source/lib/replace/libreplace.m4 b/source/lib/replace/libreplace.m4 index f06d7f83dc3..a6b1c4f5e68 100644 --- a/source/lib/replace/libreplace.m4 +++ b/source/lib/replace/libreplace.m4 @@ -152,6 +152,7 @@ AC_CHECK_FUNCS(seteuid setresuid setegid setresgid chroot bzero strerror) AC_CHECK_FUNCS(vsyslog setlinebuf mktime ftruncate chsize rename) AC_CHECK_FUNCS(waitpid strlcpy strlcat initgroups memmove strdup) AC_CHECK_FUNCS(pread pwrite strndup strcasestr strtok_r mkdtemp socketpair) +AC_CHECK_FUNCS(isatty) AC_HAVE_DECL(setresuid, [#include <unistd.h>]) AC_HAVE_DECL(setresgid, [#include <unistd.h>]) AC_HAVE_DECL(errno, [#include <errno.h>]) @@ -306,17 +307,6 @@ if test x"$samba_cv_HAVE_OPEN_O_DIRECT" = x"yes"; then fi -AC_CACHE_CHECK([that the C compiler can precompile header files],samba_cv_precompiled_headers, [ - dnl Check whether the compiler can generate precompiled headers - touch conftest.h - if ${CC-cc} conftest.h 2> /dev/null && test -f conftest.h.gch; then - precompiled_headers=yes - else - precompiled_headers=no - fi]) -AC_SUBST(precompiled_headers) - - dnl Check if the C compiler understands volatile (it should, being ANSI). AC_CACHE_CHECK([that the C compiler understands volatile],samba_cv_volatile, [ AC_TRY_COMPILE([#include <sys/types.h>],[volatile int i = 0], diff --git a/source/lib/replace/replace.h b/source/lib/replace/replace.h index 06173bd84b9..af05516e8ce 100644 --- a/source/lib/replace/replace.h +++ b/source/lib/replace/replace.h @@ -44,13 +44,6 @@ #include "win32_replace.h" #endif -#ifdef __COMPAR_FN_T -#define QSORT_CAST (__compar_fn_t) -#endif - -#ifndef QSORT_CAST -#define QSORT_CAST (int (*)(const void *, const void *)) -#endif #ifdef HAVE_STDINT_H #include <stdint.h> @@ -78,28 +71,6 @@ #include <stddef.h> #endif -/** - this is a warning hack. The idea is to use this everywhere that we - get the "discarding const" warning from gcc. That doesn't actually - fix the problem of course, but it means that when we do get to - cleaning them up we can do it by searching the code for - discard_const. - - It also means that other error types aren't as swamped by the noise - of hundreds of const warnings, so we are more likely to notice when - we get new errors. - - Please only add more uses of this macro when you find it - _really_ hard to fix const warnings. Our aim is to eventually use - this function in only a very few places. - - Also, please call this via the discard_const_p() macro interface, as that - makes the return type safe. -*/ -#define discard_const(ptr) ((void *)((intptr_t)(ptr))) - -/** Type-safe version of discard_const */ -#define discard_const_p(type, ptr) ((type *)discard_const(ptr)) #ifndef HAVE_STRERROR extern char *sys_errlist[]; @@ -363,6 +334,10 @@ ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset) #include <limits.h> #endif +#ifdef HAVE_SYS_PARAM_H +#include <sys/param.h> +#endif + /* The extra casts work around common compiler bugs. */ #define _TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) /* The outer cast is needed to work around a bug in Cray C 5.0.3.0. @@ -375,6 +350,14 @@ ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset) #define HOST_NAME_MAX 64 #endif +/* + * Some older systems seem not to have MAXHOSTNAMELEN + * defined. + */ +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN HOST_NAME_MAX +#endif + #ifndef UINT16_MAX #define UINT16_MAX 65535 #endif @@ -450,9 +433,6 @@ typedef int bool; #endif #endif -#ifdef HAVE_SYS_PARAM_H -#include <sys/param.h> -#endif #ifndef MIN #define MIN(a,b) ((a)<(b)?(a):(b)) @@ -462,11 +442,34 @@ typedef int bool; #define MAX(a,b) ((a)>(b)?(a):(b)) #endif +/** + this is a warning hack. The idea is to use this everywhere that we + get the "discarding const" warning from gcc. That doesn't actually + fix the problem of course, but it means that when we do get to + cleaning them up we can do it by searching the code for + discard_const. + + It also means that other error types aren't as swamped by the noise + of hundreds of const warnings, so we are more likely to notice when + we get new errors. + + Please only add more uses of this macro when you find it + _really_ hard to fix const warnings. Our aim is to eventually use + this function in only a very few places. + + Also, please call this via the discard_const_p() macro interface, as that + makes the return type safe. +*/ +#define discard_const(ptr) ((void *)((intptr_t)(ptr))) + +/** Type-safe version of discard_const */ +#define discard_const_p(type, ptr) ((type *)discard_const(ptr)) + #ifndef __STRING #define __STRING(x) #x #endif -#ifndef _STRINGSTRING +#ifndef __STRINGSTRING #define __STRINGSTRING(x) __STRING(x) #endif @@ -511,4 +514,12 @@ typedef int bool; #undef HAVE_MMAP #endif +#ifdef __COMPAR_FN_T +#define QSORT_CAST (__compar_fn_t) +#endif + +#ifndef QSORT_CAST +#define QSORT_CAST (int (*)(const void *, const void *)) +#endif + #endif /* _LIBREPLACE_REPLACE_H */ diff --git a/source/lib/replace/system/network.h b/source/lib/replace/system/network.h index 13d95a8ba7b..7469040b283 100644 --- a/source/lib/replace/system/network.h +++ b/source/lib/replace/system/network.h @@ -98,14 +98,6 @@ char *rep_inet_ntoa(struct in_addr ip); #define MSG_WAITALL 0 #endif -/* - * Some older systems seem not to have MAXHOSTNAMELEN - * defined. - */ -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 254 -#endif - #ifndef INADDR_LOOPBACK #define INADDR_LOOPBACK 0x7f000001 #endif diff --git a/source/lib/replace/test/testsuite.c b/source/lib/replace/test/testsuite.c index 8584bcaa667..269a2ff5d62 100644 --- a/source/lib/replace/test/testsuite.c +++ b/source/lib/replace/test/testsuite.c @@ -743,7 +743,7 @@ static int test_strtoull(void) TEST_STRTOULL("-02000000000000000000000",8, 18446744073709551615LLU, 24, ERANGE); TEST_STRTOULL("-2000000000000000000000",8, 18446744073709551615LLU, 23, ERANGE); - printf("success: strtuoll\n"); + printf("success: strtoull\n"); return true; } diff --git a/source/lib/smbrun.c b/source/lib/smbrun.c index b656822321d..26330ab992b 100644 --- a/source/lib/smbrun.c +++ b/source/lib/smbrun.c @@ -1,18 +1,18 @@ -/* +/* Unix SMB/CIFS implementation. run a command as a specified user Copyright (C) Andrew Tridgell 1992-1998 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ @@ -27,11 +27,19 @@ This is a utility function of smbrun(). ****************************************************************************/ static int setup_out_fd(void) -{ +{ int fd; - pstring path; - - slprintf(path, sizeof(path)-1, "%s/smb.XXXXXX", tmpdir()); + TALLOC_CTX *ctx = talloc_stackframe(); + char *path = NULL; + + path = talloc_asprintf(ctx, + "%s/smb.XXXXXX", + tmpdir()); + if (!path) { + TALLOC_FREE(ctx); + errno = ENOMEM; + return -1; + } /* now create the file */ fd = smb_mkstemp(path); @@ -39,6 +47,7 @@ static int setup_out_fd(void) if (fd == -1) { DEBUG(0,("setup_out_fd: Failed to create file %s. (%s)\n", path, strerror(errno) )); + TALLOC_FREE(ctx); return -1; } @@ -46,6 +55,7 @@ static int setup_out_fd(void) /* Ensure file only kept around by open fd. */ unlink(path); + TALLOC_FREE(ctx); return fd; } @@ -59,7 +69,7 @@ static int smbrun_internal(const char *cmd, int *outfd, BOOL sanitize) pid_t pid; uid_t uid = current_user.ut.uid; gid_t gid = current_user.ut.gid; - + /* * Lose any elevated privileges. */ diff --git a/source/lib/system.c b/source/lib/system.c index 9cef818fab2..ab5c06d5f67 100644 --- a/source/lib/system.c +++ b/source/lib/system.c @@ -573,7 +573,11 @@ char *sys_getwd(char *s) { char *wd; #ifdef HAVE_GETCWD +#ifdef PATH_MAX + wd = (char *)getcwd(s, PATH_MAX); +#else wd = (char *)getcwd(s, sizeof (pstring)); +#endif #else wd = (char *)getwd(s); #endif @@ -1193,178 +1197,6 @@ struct group *sys_getgrgid(gid_t gid) return getgrgid(gid); } -#if 0 /* NOT CURRENTLY USED - JRA */ -/************************************************************************** - The following are the UNICODE versions of *all* system interface functions - called within Samba. Ok, ok, the exceptions are the gethostbyXX calls, - which currently are left as ascii as they are not used other than in name - resolution. -****************************************************************************/ - -/************************************************************************** - Wide stat. Just narrow and call sys_xxx. -****************************************************************************/ - -int wsys_stat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf) -{ - pstring fname; - return sys_stat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf); -} - -/************************************************************************** - Wide lstat. Just narrow and call sys_xxx. -****************************************************************************/ - -int wsys_lstat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf) -{ - pstring fname; - return sys_lstat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf); -} - -/************************************************************************** - Wide creat. Just narrow and call sys_xxx. -****************************************************************************/ - -int wsys_creat(const smb_ucs2_t *wfname, mode_t mode) -{ - pstring fname; - return sys_creat(unicode_to_unix(fname,wfname,sizeof(fname)), mode); -} - -/************************************************************************** - Wide open. Just narrow and call sys_xxx. -****************************************************************************/ - -int wsys_open(const smb_ucs2_t *wfname, int oflag, mode_t mode) -{ - pstring fname; - return sys_open(unicode_to_unix(fname,wfname,sizeof(fname)), oflag, mode); -} - -/************************************************************************** - Wide fopen. Just narrow and call sys_xxx. -****************************************************************************/ - -FILE *wsys_fopen(const smb_ucs2_t *wfname, const char *type) -{ - pstring fname; - return sys_fopen(unicode_to_unix(fname,wfname,sizeof(fname)), type); -} - -/************************************************************************** - Wide opendir. Just narrow and call sys_xxx. -****************************************************************************/ - -SMB_STRUCT_DIR *wsys_opendir(const smb_ucs2_t *wfname) -{ - pstring fname; - return opendir(unicode_to_unix(fname,wfname,sizeof(fname))); -} - -/************************************************************************** - Wide readdir. Return a structure pointer containing a wide filename. -****************************************************************************/ - -SMB_STRUCT_WDIRENT *wsys_readdir(SMB_STRUCT_DIR *dirp) -{ - static SMB_STRUCT_WDIRENT retval; - SMB_STRUCT_DIRENT *dirval = sys_readdir(dirp); - - if(!dirval) - return NULL; - - /* - * The only POSIX defined member of this struct is d_name. - */ - - unix_to_unicode(retval.d_name,dirval->d_name,sizeof(retval.d_name)); - - return &retval; -} - -/************************************************************************** - Wide getwd. Call sys_xxx and widen. Assumes s points to a wpstring. -****************************************************************************/ - -smb_ucs2_t *wsys_getwd(smb_ucs2_t *s) -{ - pstring fname; - char *p = sys_getwd(fname); - - if(!p) - return NULL; - - return unix_to_unicode(s, p, sizeof(wpstring)); -} - -/************************************************************************** - Wide chown. Just narrow and call sys_xxx. -****************************************************************************/ - -int wsys_chown(const smb_ucs2_t *wfname, uid_t uid, gid_t gid) -{ - pstring fname; - return chown(unicode_to_unix(fname,wfname,sizeof(fname)), uid, gid); -} - -/************************************************************************** - Wide chroot. Just narrow and call sys_xxx. -****************************************************************************/ - -int wsys_chroot(const smb_ucs2_t *wfname) -{ - pstring fname; - return chroot(unicode_to_unix(fname,wfname,sizeof(fname))); -} - -/************************************************************************** - Wide getpwnam. Return a structure pointer containing wide names. -****************************************************************************/ - -SMB_STRUCT_WPASSWD *wsys_getpwnam(const smb_ucs2_t *wname) -{ - static SMB_STRUCT_WPASSWD retval; - fstring name; - struct passwd *pwret = sys_getpwnam(unicode_to_unix(name,wname,sizeof(name))); - - if(!pwret) - return NULL; - - unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name)); - retval.pw_passwd = pwret->pw_passwd; - retval.pw_uid = pwret->pw_uid; - retval.pw_gid = pwret->pw_gid; - unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos)); - unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir)); - unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell)); - - return &retval; -} - -/************************************************************************** - Wide getpwuid. Return a structure pointer containing wide names. -****************************************************************************/ - -SMB_STRUCT_WPASSWD *wsys_getpwuid(uid_t uid) -{ - static SMB_STRUCT_WPASSWD retval; - struct passwd *pwret = sys_getpwuid(uid); - - if(!pwret) - return NULL; - - unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name)); - retval.pw_passwd = pwret->pw_passwd; - retval.pw_uid = pwret->pw_uid; - retval.pw_gid = pwret->pw_gid; - unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos)); - unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir)); - unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell)); - - return &retval; -} -#endif /* NOT CURRENTLY USED - JRA */ - /************************************************************************** Extract a command into an arg list. ****************************************************************************/ diff --git a/source/lib/talloc/configure.ac b/source/lib/talloc/configure.ac index 5f465fe93ab..afc2a944f01 100644 --- a/source/lib/talloc/configure.ac +++ b/source/lib/talloc/configure.ac @@ -1,5 +1,5 @@ AC_PREREQ(2.50) -AC_INIT(talloc, 1.0) +AC_INIT(talloc, 1.1.0) AC_CONFIG_SRCDIR([talloc.c]) AC_SUBST(datarootdir) AC_CONFIG_HEADER(config.h) diff --git a/source/lib/talloc/talloc.c b/source/lib/talloc/talloc.c index c073a8c7743..4d72c0e871a 100644 --- a/source/lib/talloc/talloc.c +++ b/source/lib/talloc/talloc.c @@ -1109,64 +1109,132 @@ void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name return newp; } +static inline char *__talloc_strlendup(const void *t, const char *p, size_t len) +{ + char *ret; + + ret = (char *)__talloc(t, len + 1); + if (unlikely(!ret)) return NULL; + + memcpy(ret, p, len); + ret[len] = 0; + + _talloc_set_name_const(ret, ret); + return ret; +} + /* - strdup with a talloc + strdup with a talloc */ char *talloc_strdup(const void *t, const char *p) { + if (unlikely(!p)) return NULL; + return __talloc_strlendup(t, p, strlen(p)); +} + +/* + strndup with a talloc +*/ +char *talloc_strndup(const void *t, const char *p, size_t n) +{ + if (unlikely(!p)) return NULL; + return __talloc_strlendup(t, p, strnlen(p, n)); +} + +static inline char *__talloc_strlendup_append(char *s, size_t slen, + const char *a, size_t alen) +{ char *ret; - if (!p) { - return NULL; + + ret = talloc_realloc(NULL, s, char, slen + alen + 1); + if (unlikely(!ret)) return NULL; + + /* append the string and the trailing \0 */ + memcpy(&ret[slen], a, alen); + ret[slen+alen] = 0; + + _talloc_set_name_const(ret, ret); + return ret; +} + +/* + * Appends at the end of the string. + */ +char *talloc_strdup_append(char *s, const char *a) +{ + if (unlikely(!s)) { + return talloc_strdup(NULL, a); } - ret = (char *)talloc_memdup(t, p, strlen(p) + 1); - if (likely(ret)) { - _talloc_set_name_const(ret, ret); + + if (unlikely(!a)) { + return s; } - return ret; + + return __talloc_strlendup_append(s, strlen(s), a, strlen(a)); } /* - append to a talloced string -*/ -char *talloc_append_string(const void *t, char *orig, const char *append) + * Appends at the end of the talloc'ed buffer, + * not the end of the string. + */ +char *talloc_strdup_append_buffer(char *s, const char *a) { - char *ret; - size_t olen = strlen(orig); - size_t alenz; + size_t slen; - if (!append) - return orig; + if (unlikely(!s)) { + return talloc_strdup(NULL, a); + } - alenz = strlen(append) + 1; + if (unlikely(!a)) { + return s; + } - ret = talloc_realloc(t, orig, char, olen + alenz); - if (!ret) - return NULL; + slen = talloc_get_size(s); + if (likely(slen > 0)) { + slen--; + } - /* append the string with the trailing \0 */ - memcpy(&ret[olen], append, alenz); + return __talloc_strlendup_append(s, slen, a, strlen(a)); +} - _talloc_set_name_const(ret, ret); +/* + * Appends at the end of the string. + */ +char *talloc_strndup_append(char *s, const char *a, size_t n) +{ + if (unlikely(!s)) { + return talloc_strdup(NULL, a); + } - return ret; + if (unlikely(!a)) { + return s; + } + + return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n)); } /* - strndup with a talloc -*/ -char *talloc_strndup(const void *t, const char *p, size_t n) + * Appends at the end of the talloc'ed buffer, + * not the end of the string. + */ +char *talloc_strndup_append_buffer(char *s, const char *a, size_t n) { - size_t len; - char *ret; + size_t slen; - for (len=0; len<n && p[len]; len++) ; + if (unlikely(!s)) { + return talloc_strdup(NULL, a); + } - ret = (char *)__talloc(t, len + 1); - if (!ret) { return NULL; } - memcpy(ret, p, len); - ret[len] = 0; - _talloc_set_name_const(ret, ret); - return ret; + if (unlikely(!a)) { + return s; + } + + slen = talloc_get_size(s); + if (likely(slen > 0)) { + slen--; + } + + return __talloc_strlendup_append(s, slen, a, strnlen(a, n)); } #ifndef HAVE_VA_COPY @@ -1188,18 +1256,18 @@ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) va_copy(ap2, ap); len = vsnprintf(&c, 1, fmt, ap2); va_end(ap2); - if (len < 0) { + if (unlikely(len < 0)) { return NULL; } ret = (char *)__talloc(t, len+1); - if (ret) { - va_copy(ap2, ap); - vsnprintf(ret, len+1, fmt, ap2); - va_end(ap2); - _talloc_set_name_const(ret, ret); - } + if (unlikely(!ret)) return NULL; + + va_copy(ap2, ap); + vsnprintf(ret, len+1, fmt, ap2); + va_end(ap2); + _talloc_set_name_const(ret, ret); return ret; } @@ -1219,52 +1287,78 @@ char *talloc_asprintf(const void *t, const char *fmt, ...) return ret; } +static inline char *__talloc_vaslenprintf_append(char *s, size_t slen, + const char *fmt, va_list ap) + PRINTF_ATTRIBUTE(3,0); -/** - * Realloc @p s to append the formatted result of @p fmt and @p ap, - * and return @p s, which may have moved. Good for gradually - * accumulating output into a string buffer. - **/ -char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) -{ - struct talloc_chunk *tc; - int len, s_len; +static inline char *__talloc_vaslenprintf_append(char *s, size_t slen, + const char *fmt, va_list ap) +{ + ssize_t alen; va_list ap2; char c; - if (s == NULL) { - return talloc_vasprintf(NULL, fmt, ap); - } - - tc = talloc_chunk_from_ptr(s); - - s_len = tc->size - 1; - va_copy(ap2, ap); - len = vsnprintf(&c, 1, fmt, ap2); + alen = vsnprintf(&c, 1, fmt, ap2); va_end(ap2); - if (len <= 0) { + if (alen <= 0) { /* Either the vsnprintf failed or the format resulted in * no characters being formatted. In the former case, we * ought to return NULL, in the latter we ought to return - * the original string. Most current callers of this + * the original string. Most current callers of this * function expect it to never return NULL. */ return s; } - s = talloc_realloc(NULL, s, char, s_len + len+1); + s = talloc_realloc(NULL, s, char, slen + alen + 1); if (!s) return NULL; va_copy(ap2, ap); - vsnprintf(s+s_len, len+1, fmt, ap2); + vsnprintf(s + slen, alen + 1, fmt, ap2); va_end(ap2); - _talloc_set_name_const(s, s); + _talloc_set_name_const(s, s); return s; } +/** + * Realloc @p s to append the formatted result of @p fmt and @p ap, + * and return @p s, which may have moved. Good for gradually + * accumulating output into a string buffer. Appends at the end + * of the string. + **/ +char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) +{ + if (unlikely(!s)) { + return talloc_vasprintf(NULL, fmt, ap); + } + + return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap); +} + +/** + * Realloc @p s to append the formatted result of @p fmt and @p ap, + * and return @p s, which may have moved. Always appends at the + * end of the talloc'ed buffer, not the end of the string. + **/ +char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) +{ + size_t slen; + + if (unlikely(!s)) { + return talloc_vasprintf(NULL, fmt, ap); + } + + slen = talloc_get_size(s); + if (likely(slen > 0)) { + slen--; + } + + return __talloc_vaslenprintf_append(s, slen, fmt, ap); +} + /* Realloc @p s to append the formatted result of @p fmt and return @p s, which may have moved. Good for gradually accumulating output @@ -1281,6 +1375,21 @@ char *talloc_asprintf_append(char *s, const char *fmt, ...) } /* + Realloc @p s to append the formatted result of @p fmt and return @p + s, which may have moved. Good for gradually accumulating output + into a buffer. + */ +char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + s = talloc_vasprintf_append_buffer(s, fmt, ap); + va_end(ap); + return s; +} + +/* alloc an array, checking for integer overflow in the array size */ void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name) diff --git a/source/lib/talloc/talloc.h b/source/lib/talloc/talloc.h index 15130d0d982..e1033916817 100644 --- a/source/lib/talloc/talloc.h +++ b/source/lib/talloc/talloc.h @@ -111,6 +111,7 @@ typedef void TALLOC_CTX; #define talloc_array_p(ctx, type, count) talloc_array(ctx, type, count) #define talloc_realloc_p(ctx, p, type, count) talloc_realloc(ctx, p, type, count) #define talloc_destroy(ctx) talloc_free(ctx) +#define talloc_append_string(c, s, a) (s?talloc_strdup_append(s,a):talloc_strdup(c, a)) #endif /* The following definitions come from talloc.c */ @@ -152,13 +153,6 @@ void talloc_enable_leak_report(void); void talloc_enable_leak_report_full(void); void *_talloc_zero(const void *ctx, size_t size, const char *name); void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name); -char *talloc_strdup(const void *t, const char *p); -char *talloc_strndup(const void *t, const char *p, size_t n); -char *talloc_append_string(const void *t, char *orig, const char *append); -char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); -char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); -char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); -char *talloc_asprintf_append(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name); void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name); void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name); @@ -169,4 +163,20 @@ void *talloc_find_parent_byname(const void *ctx, const char *name); void talloc_show_parents(const void *context, FILE *file); int talloc_is_parent(const void *context, const void *ptr); +char *talloc_strdup(const void *t, const char *p); +char *talloc_strdup_append(char *s, const char *a); +char *talloc_strdup_append_buffer(char *s, const char *a); + +char *talloc_strndup(const void *t, const char *p, size_t n); +char *talloc_strndup_append(char *s, const char *a, size_t n); +char *talloc_strndup_append_buffer(char *s, const char *a, size_t n); + +char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); +char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); +char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); + +char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); +char *talloc_asprintf_append(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); +char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); + #endif diff --git a/source/lib/talloc/talloc_guide.txt b/source/lib/talloc/talloc_guide.txt index c4634ae19a9..18663b370d9 100644 --- a/source/lib/talloc/talloc_guide.txt +++ b/source/lib/talloc/talloc_guide.txt @@ -568,8 +568,23 @@ string. This is equivalent to: =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- char *talloc_asprintf_append(char *s, const char *fmt, ...); +The talloc_asprintf_append() function appends the given formatted +string to the given string. +Use this varient when the string in the current talloc buffer may +have been truncated in length. + +This functions sets the name of the new pointer to the new +string. This is equivalent to: + talloc_set_name_const(ptr, ptr) + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...); + The talloc_asprintf_append() function appends the given formatted -string to the given string. +string to the end of the currently allocated talloc buffer. +Use this varient when the string in the current talloc buffer has +not been changed. This functions sets the name of the new pointer to the new string. This is equivalent to: @@ -577,7 +592,7 @@ string. This is equivalent to: =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -(type *)talloc_array(const void *ctx, type, uint_t count); +((type *)talloc_array(const void *ctx, type, uint_t count); The talloc_array() macro is equivalent to: diff --git a/source/lib/talloc/testsuite.c b/source/lib/talloc/testsuite.c index 2e3ae65082f..e16c91f8b9c 100644 --- a/source/lib/talloc/testsuite.c +++ b/source/lib/talloc/testsuite.c @@ -106,7 +106,7 @@ static bool test_ref1(void) { void *root, *p1, *p2, *ref, *r1; - printf("test: ref1 [\nSINGLE REFERENCE FREE\n]\n"); + printf("test: ref1\n# SINGLE REFERENCE FREE\n"); root = talloc_named_const(NULL, 0, "root"); p1 = talloc_named_const(root, 1, "p1"); @@ -162,7 +162,7 @@ static bool test_ref2(void) { void *root, *p1, *p2, *ref, *r1; - printf("test: ref2 [\nDOUBLE REFERENCE FREE\n]\n"); + printf("test: ref2\n# DOUBLE REFERENCE FREE\n"); root = talloc_named_const(NULL, 0, "root"); p1 = talloc_named_const(root, 1, "p1"); talloc_named_const(p1, 1, "x1"); @@ -217,7 +217,7 @@ static bool test_ref3(void) { void *root, *p1, *p2, *ref, *r1; - printf("test: ref3 [\nPARENT REFERENCE FREE\n]\n"); + printf("test: ref3\n# PARENT REFERENCE FREE\n"); root = talloc_named_const(NULL, 0, "root"); p1 = talloc_named_const(root, 1, "p1"); @@ -256,7 +256,7 @@ static bool test_ref4(void) { void *root, *p1, *p2, *ref, *r1; - printf("test: ref4 [\nREFERRER REFERENCE FREE\n]\n"); + printf("test: ref4\n# REFERRER REFERENCE FREE\n"); root = talloc_named_const(NULL, 0, "root"); p1 = talloc_named_const(root, 1, "p1"); @@ -306,7 +306,7 @@ static bool test_unlink1(void) { void *root, *p1, *p2, *ref, *r1; - printf("test: unlink [\nUNLINK\n]\n"); + printf("test: unlink\n# UNLINK\n"); root = talloc_named_const(NULL, 0, "root"); p1 = talloc_named_const(root, 1, "p1"); @@ -358,7 +358,7 @@ static bool test_misc(void) double *d; const char *name; - printf("test: misc [\nMISCELLANEOUS\n]\n"); + printf("test: misc\n# MISCELLANEOUS\n"); root = talloc_new(NULL); @@ -419,15 +419,15 @@ static bool test_misc(void) p2 = talloc_strndup(p1, "foo", 2); torture_assert("misc", strcmp("fo", p2) == 0, "strndup doesn't work\n"); - p2 = talloc_asprintf_append(p2, "o%c", 'd'); + p2 = talloc_asprintf_append_buffer(p2, "o%c", 'd'); torture_assert("misc", strcmp("food", p2) == 0, - "talloc_asprintf_append doesn't work\n"); + "talloc_asprintf_append_buffer doesn't work\n"); CHECK_BLOCKS("misc", p2, 1); CHECK_BLOCKS("misc", p1, 3); - p2 = talloc_asprintf_append(NULL, "hello %s", "world"); + p2 = talloc_asprintf_append_buffer(NULL, "hello %s", "world"); torture_assert("misc", strcmp("hello world", p2) == 0, - "talloc_asprintf_append doesn't work\n"); + "talloc_asprintf_append_buffer doesn't work\n"); CHECK_BLOCKS("misc", p2, 1); CHECK_BLOCKS("misc", p1, 3); talloc_free(p2); @@ -509,7 +509,7 @@ static bool test_realloc(void) { void *root, *p1, *p2; - printf("test: realloc [\nREALLOC\n]\n"); + printf("test: realloc\n# REALLOC\n"); root = talloc_new(NULL); @@ -553,7 +553,7 @@ static bool test_realloc(void) talloc_free(root); - printf("success: REALLOC\n"); + printf("success: realloc\n"); return true; } @@ -617,7 +617,7 @@ static bool test_type(void) }; struct el1 *el1; - printf("test: type [\ntalloc type checking\n]\n"); + printf("test: type\n# talloc type checking\n"); root = talloc_new(NULL); @@ -646,7 +646,7 @@ static bool test_steal(void) { void *root, *p1, *p2; - printf("test: steal [\nSTEAL\n]\n"); + printf("test: steal\n# STEAL\n"); root = talloc_new(NULL); @@ -702,7 +702,7 @@ static bool test_move(void) int *x; } *t1, *t2; - printf("test: move [\nMOVE\n]\n"); + printf("test: move\n# MOVE\n"); root = talloc_new(NULL); @@ -732,7 +732,7 @@ static bool test_realloc_fn(void) { void *root, *p1; - printf("test: realloc_fn [\ntalloc_realloc_fn\n]\n"); + printf("test: realloc_fn\n# talloc_realloc_fn\n"); root = talloc_new(NULL); @@ -757,7 +757,7 @@ static bool test_unref_reparent(void) { void *root, *p1, *p2, *c1; - printf("test: unref_reparent [\nUNREFERENCE AFTER PARENT FREED\n]\n"); + printf("test: unref_reparent\n# UNREFERENCE AFTER PARENT FREED\n"); root = talloc_named_const(NULL, 0, "root"); p1 = talloc_named_const(root, 1, "orig parent"); @@ -794,7 +794,7 @@ static bool test_speed(void) int i; struct timeval tv; - printf("test: speed [\nTALLOC VS MALLOC SPEED\n]\n"); + printf("test: speed\n# TALLOC VS MALLOC SPEED\n"); tv = timeval_current(); count = 0; @@ -840,7 +840,7 @@ static bool test_lifeless(void) char *parent, *child; void *child_owner = talloc_new(NULL); - printf("test: lifeless [\nTALLOC_UNLINK LOOP\n]\n"); + printf("test: lifeless\n# TALLOC_UNLINK LOOP\n"); parent = talloc_strdup(top, "parent"); child = talloc_strdup(parent, "child"); @@ -874,7 +874,7 @@ static bool test_loop(void) char *req2, *req3; } *req1; - printf("test: loop [\nTALLOC LOOP DESTRUCTION\n]\n"); + printf("test: loop\n# TALLOC LOOP DESTRUCTION\n"); parent = talloc_strdup(top, "parent"); req1 = talloc(parent, struct req1); @@ -908,7 +908,7 @@ static bool test_free_parent_deny_child(void) char *level2; char *level3; - printf("test: free_parent_deny_child [\nTALLOC FREE PARENT DENY CHILD\n]\n"); + printf("test: free_parent_deny_child\n# TALLOC FREE PARENT DENY CHILD\n"); level1 = talloc_strdup(top, "level1"); level2 = talloc_strdup(level1, "level2"); @@ -938,7 +938,7 @@ static bool test_talloc_ptrtype(void) const char *location3; const char *location4; - printf("test: ptrtype [\nTALLOC PTRTYPE\n]\n"); + printf("test: ptrtype\n# TALLOC PTRTYPE\n"); s1 = talloc_ptrtype(top, s1);location1 = __location__; @@ -1024,7 +1024,7 @@ static bool test_talloc_free_in_destructor(void) void *level4; void **level5; - printf("test: free_in_destructor [\nTALLOC FREE IN DESTRUCTOR\n]\n"); + printf("test: free_in_destructor\n# TALLOC FREE IN DESTRUCTOR\n"); level0 = talloc_new(NULL); level1 = talloc_new(level0); @@ -1053,7 +1053,7 @@ static bool test_autofree(void) #if _SAMBA_BUILD_ < 4 /* autofree test would kill smbtorture */ void *p; - printf("test: autofree [\nTALLOC AUTOFREE CONTEXT\n]\n"); + printf("test: autofree\n# TALLOC AUTOFREE CONTEXT\n"); p = talloc_autofree_context(); talloc_free(p); diff --git a/source/lib/util.c b/source/lib/util.c index cf39c0980d0..516598b357e 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -1557,20 +1557,22 @@ BOOL process_exists_by_pid(pid_t pid) const char *uidtoname(uid_t uid) { - fstring name; - struct passwd *pass; + TALLOC_CTX *ctx = talloc_tos(); + char *name = NULL; + struct passwd *pass = NULL; - pass = getpwuid_alloc(talloc_tos(), uid); + pass = getpwuid_alloc(ctx,uid); if (pass) { - fstrcpy(name, pass->pw_name); + name = talloc_strdup(ctx,pass->pw_name); TALLOC_FREE(pass); } else { - slprintf(name, sizeof(name) - 1, "%ld",(long int)uid); + name = talloc_asprintf(ctx, + "%ld", + (long int)uid); } - return talloc_strdup(talloc_tos(), name); + return name; } - /******************************************************************* Convert a gid into a group name. ********************************************************************/ diff --git a/source/lib/util_str.c b/source/lib/util_str.c index bac94740cd7..fbd9c1ca6da 100644 --- a/source/lib/util_str.c +++ b/source/lib/util_str.c @@ -6,6 +6,7 @@ Copyright (C) Simo Sorce 2001-2002 Copyright (C) Martin Pool 2003 Copyright (C) James Peach 2006 + Copyright (C) Jeremy Allison 1992-2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -264,12 +265,63 @@ int StrCaseCmp(const char *s, const char *t) /** Case insensitive string compararison, length limited. **/ -int StrnCaseCmp(const char *s, const char *t, size_t n) +int StrnCaseCmp(const char *s, const char *t, size_t len) { - pstring buf1, buf2; - unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1)); - unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2)); - return strncmp(buf1,buf2,n); + size_t n = 0; + const char *ps, *pt; + size_t size; + smb_ucs2_t *buffer_s, *buffer_t; + int ret; + + for (ps = s, pt = t; n < len ; ps++, pt++, n++) { + char us, ut; + + if (!*ps && !*pt) + return 0; /* both ended */ + else if (!*ps) + return -1; /* s is a prefix */ + else if (!*pt) + return +1; /* t is a prefix */ + else if ((*ps & 0x80) || (*pt & 0x80)) + /* not ascii anymore, do it the + * hard way from here on in */ + break; + + us = toupper_ascii(*ps); + ut = toupper_ascii(*pt); + if (us == ut) + continue; + else if (us < ut) + return -1; + else if (us > ut) + return +1; + } + + if (n == len) { + return 0; + } + + size = push_ucs2_allocate(&buffer_s, ps); + if (size == (size_t)-1) { + return strncmp(ps, pt, len-n); + /* Not quite the right answer, but finding the right one + under this failure case is expensive, + and it's pretty close */ + } + + size = push_ucs2_allocate(&buffer_t, pt); + if (size == (size_t)-1) { + SAFE_FREE(buffer_s); + return strncmp(ps, pt, len-n); + /* Not quite the right answer, but finding the right one + under this failure case is expensive, + and it's pretty close */ + } + + ret = strncasecmp_w(buffer_s, buffer_t, len-n); + SAFE_FREE(buffer_s); + SAFE_FREE(buffer_t); + return ret; } /** @@ -283,7 +335,7 @@ BOOL strequal(const char *s1, const char *s2) return(True); if (!s1 || !s2) return(False); - + return(StrCaseCmp(s1,s2)==0); } @@ -298,7 +350,7 @@ BOOL strnequal(const char *s1,const char *s2,size_t n) return(True); if (!s1 || !s2 || !n) return(False); - + return(StrnCaseCmp(s1,s2,n)==0); } @@ -353,11 +405,16 @@ int strwicmp(const char *psz1, const char *psz2) char *strupper_static(const char *s) { - static pstring str; + static char *str = NULL; - pstrcpy(str, s); + if (str) { + SAFE_FREE(str); + } + str = SMB_STRDUP(s); + if (!str) { + return CONST_DISCARD(char *,s); + } strupper_m(str); - return str; } @@ -381,7 +438,7 @@ BOOL strisnormal(const char *s, int case_default) { if (case_default == CASE_UPPER) return(!strhaslower(s)); - + return(!strhasupper(s)); } @@ -390,12 +447,9 @@ BOOL strisnormal(const char *s, int case_default) String replace. NOTE: oldc and newc must be 7 bit characters **/ - -void string_replace( pstring s, char oldc, char newc ) +void string_replace( char *s, char oldc, char newc ) { char *p; - smb_ucs2_t *tmp; - size_t len; /* this is quite a common operation, so we want it to be fast. We optimise for the ascii case, knowing that all our @@ -405,8 +459,9 @@ void string_replace( pstring s, char oldc, char newc ) for (p = s; *p; p++) { if (*p & 0x80) /* mb string - slow path. */ break; - if (*p == oldc) + if (*p == oldc) { *p = newc; + } } if (!*p) @@ -417,13 +472,18 @@ void string_replace( pstring s, char oldc, char newc ) /* With compose characters we must restart from the beginning. JRA. */ p = s; #endif - len = push_ucs2_allocate(&tmp, p); - if (len == -1) { - return; + + while (*p) { + size_t c_size; + next_codepoint(p, &c_size); + + if (c_size == 1) { + if (*p == oldc) { + *p = newc; + } + } + p += c_size; } - string_replace_w(tmp, UCS2_CHAR(oldc), UCS2_CHAR(newc)); - pull_ucs2(NULL, p, tmp, len/2, -1, STR_TERMINATE); - SAFE_FREE(tmp); } /** @@ -470,9 +530,14 @@ char *skip_string(const char *base, size_t len, char *buf) size_t str_charnum(const char *s) { - uint16 tmpbuf2[sizeof(pstring)]; - push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE); - return strlen_w(tmpbuf2); + size_t ret; + smb_ucs2_t *tmpbuf2 = NULL; + if (push_ucs2_allocate(&tmpbuf2, s) == (size_t)-1) { + return 0; + } + ret = strlen_w(tmpbuf2); + SAFE_FREE(tmpbuf2); + return ret; } /** @@ -483,9 +548,14 @@ size_t str_charnum(const char *s) size_t str_ascii_charnum(const char *s) { - pstring tmpbuf2; - push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE); - return strlen(tmpbuf2); + size_t ret; + char *tmpbuf2 = NULL; + if (push_ascii_allocate(&tmpbuf2, s) == (size_t)-1) { + return 0; + } + ret = strlen(tmpbuf2); + SAFE_FREE(tmpbuf2); + return ret; } BOOL trim_char(char *s,char cfront,char cback) @@ -913,22 +983,38 @@ char *hex_encode(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len) BOOL in_list(const char *s, const char *list, BOOL casesensitive) { - pstring tok; + char *tok; const char *p=list; + size_t bufsize = strlen(list); + BOOL ret = False; if (!list) return(False); - while (next_token(&p,tok,LIST_SEP,sizeof(tok))) { + /* We know a token can't be larger + * than the entire list. */ + + tok = SMB_MALLOC_ARRAY(char, bufsize+1); + if (!tok) { + return False; + } + + while (next_token(&p,tok,LIST_SEP,bufsize+1)) { if (casesensitive) { - if (strcmp(tok,s) == 0) - return(True); + if (strcmp(tok,s) == 0) { + ret = True; + break; + } } else { - if (StrCaseCmp(tok,s) == 0) - return(True); + if (StrCaseCmp(tok,s) == 0) { + ret = True; + break; + } } } - return(False); + + SAFE_FREE(tok); + return ret; } /* this is used to prevent lots of mallocs of size 1 */ @@ -1376,10 +1462,11 @@ char *string_truncate(char *s, unsigned int length) char *strchr_m(const char *src, char c) { - wpstring ws; - pstring s2; + smb_ucs2_t *ws = NULL; + char *s2 = NULL; smb_ucs2_t *p; const char *s; + char *ret; /* characters below 0x3F are guaranteed to not appear in non-initial position in multi-byte charsets */ @@ -1405,13 +1492,25 @@ char *strchr_m(const char *src, char c) s = src; #endif - push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE); + if (push_ucs2_allocate(&ws, s)==(size_t)-1) { + /* Wrong answer, but what can we do... */ + return strchr(src, c); + } p = strchr_w(ws, UCS2_CHAR(c)); - if (!p) + if (!p) { + SAFE_FREE(ws); return NULL; + } *p = 0; - pull_ucs2_pstring(s2, ws); - return (char *)(s+strlen(s2)); + if (pull_ucs2_allocate(&s2, ws)==(size_t)-1) { + SAFE_FREE(ws); + /* Wrong answer, but what can we do... */ + return strchr(src, c); + } + ret = (char *)(s+strlen(s2)); + SAFE_FREE(ws); + SAFE_FREE(s2); + return ret; } char *strrchr_m(const char *s, char c) @@ -1457,17 +1556,30 @@ char *strrchr_m(const char *s, char c) /* String contained a non-ascii char. Slow path. */ { - wpstring ws; - pstring s2; + smb_ucs2_t *ws = NULL; + char *s2 = NULL; smb_ucs2_t *p; + char *ret; - push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE); + if (push_ucs2_allocate(&ws,s)==(size_t)-1) { + /* Wrong answer, but what can we do. */ + return strrchr(s, c); + } p = strrchr_w(ws, UCS2_CHAR(c)); - if (!p) + if (!p) { + SAFE_FREE(ws); return NULL; + } *p = 0; - pull_ucs2_pstring(s2, ws); - return (char *)(s+strlen(s2)); + if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) { + SAFE_FREE(ws); + /* Wrong answer, but what can we do. */ + return strrchr(s, c); + } + ret = (char *)(s+strlen(s2)); + SAFE_FREE(ws); + SAFE_FREE(s2); + return ret; } } @@ -1478,17 +1590,30 @@ char *strrchr_m(const char *s, char c) char *strnrchr_m(const char *s, char c, unsigned int n) { - wpstring ws; - pstring s2; + smb_ucs2_t *ws = NULL; + char *s2 = NULL; smb_ucs2_t *p; + char *ret; - push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE); + if (push_ucs2_allocate(&ws,s)==(size_t)-1) { + /* Too hard to try and get right. */ + return NULL; + } p = strnrchr_w(ws, UCS2_CHAR(c), n); - if (!p) + if (!p) { + SAFE_FREE(ws); return NULL; + } *p = 0; - pull_ucs2_pstring(s2, ws); - return (char *)(s+strlen(s2)); + if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) { + SAFE_FREE(ws); + /* Too hard to try and get right. */ + return NULL; + } + ret = (char *)(s+strlen(s2)); + SAFE_FREE(ws); + SAFE_FREE(s2); + return ret; } /*********************************************************************** @@ -1794,7 +1919,7 @@ static char **str_list_make_internal(TALLOC_CTX *mem_ctx, const char *string, co char *s; int num, lsize; pstring tok; - + if (!string || !*string) return NULL; if (mem_ctx) { @@ -1807,12 +1932,12 @@ static char **str_list_make_internal(TALLOC_CTX *mem_ctx, const char *string, co return NULL; } if (!sep) sep = LIST_SEP; - + num = lsize = 0; list = NULL; - + str = s; - while (next_token(&str, tok, sep, sizeof(tok))) { + while (next_token(&str, tok, sep, sizeof(tok))) { if (num == lsize) { lsize += S_LIST_ABS; if (mem_ctx) { @@ -1842,7 +1967,7 @@ static char **str_list_make_internal(TALLOC_CTX *mem_ctx, const char *string, co } else { list[num] = SMB_STRDUP(tok); } - + if (!list[num]) { DEBUG(0,("str_list_make: Unable to allocate memory")); str_list_free(&list); diff --git a/source/lib/util_unistr.c b/source/lib/util_unistr.c index a4952d137ee..64cfd521202 100644 --- a/source/lib/util_unistr.c +++ b/source/lib/util_unistr.c @@ -361,7 +361,7 @@ int rpcstr_push(void* dest, const char *src, size_t dest_len, int flags) void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen) { - if (str == NULL) { + if ((str == NULL) || (str->uni_str_len == 0)) { *dest='\0'; return; } @@ -374,7 +374,7 @@ void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen) void unistr3_to_ascii(char *dest, const UNISTR3 *str, size_t maxlen) { - if (str == NULL) { + if ((str == NULL) || (str->uni_str_len == 0)) { *dest='\0'; return; } |