/* copy over the token */
pbuf = buff;
for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
- if (*s == '\"') {
+ if ( *s == '\"' ) {
quoted = !quoted;
} else {
len++;
*ctok=ictok;
s=(char *)last_ptr;
- if (!(ret=iret=malloc(ictok*sizeof(char *))))
+ if (!(ret=iret=SMB_MALLOC_ARRAY(char *,ictok+1)))
return NULL;
while(ictok--) {
*iret++=s;
- while(*s++)
- ;
- while(!*s)
- s++;
+ if (ictok > 0) {
+ while(*s++)
+ ;
+ while(!*s)
+ s++;
+ }
}
+ ret[*ctok] = NULL;
return ret;
}
Convert a string to "normal" form.
**/
-void strnorm(char *s)
+void strnorm(char *s, int case_default)
{
- extern int case_default;
if (case_default == CASE_UPPER)
strupper_m(s);
else
Check if a string is in "normal" case.
**/
-BOOL strisnormal(const char *s)
+BOOL strisnormal(const char *s, int case_default)
{
- extern int case_default;
if (case_default == CASE_UPPER)
return(!strhaslower(s));
NOTE: oldc and newc must be 7 bit characters
**/
-void string_replace(pstring s,char oldc,char newc)
+void string_replace( pstring s, char oldc, char newc )
{
- unsigned char *p;
+ char *p;
/* 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) */
- for (p = (unsigned char *)s; *p; p++) {
+ for (p = s; *p; p++) {
if (*p & 0x80) /* mb string - slow path. */
break;
if (*p == oldc)
{
smb_ucs2_t *ptr;
int count;
- push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
- for(count=0,ptr=tmpbuf;*ptr;ptr++)
+ smb_ucs2_t *alloc_tmpbuf = NULL;
+
+ if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {
+ return 0;
+ }
+
+ for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)
if(*ptr==UCS2_CHAR(c))
count++;
+
+ SAFE_FREE(alloc_tmpbuf);
return(count);
}
size_t len;
if (!dest) {
- DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
+ DEBUG(0,("ERROR: NULL dest in safe_strcpy, called from [%s][%d]\n", fn, line));
return NULL;
}
size_t src_len, dest_len;
if (!dest) {
- DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
+ DEBUG(0,("ERROR: NULL dest in safe_strcat, called from [%s][%d]\n", fn, line));
return NULL;
}
#endif
if (!dest) {
- DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
+ DEBUG(0,("ERROR: NULL dest in alpha_strcpy, called from [%s][%d]\n", fn, line));
return NULL;
}
clobber_region(fn, line, dest, n+1);
#endif
- if (!dest)
+ if (!dest) {
+ DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn, line));
return(NULL);
-
+ }
+
if (!src) {
*dest = 0;
return(dest);
return num_chars;
}
+DATA_BLOB strhex_to_data_blob(const char *strhex)
+{
+ DATA_BLOB ret_blob = data_blob(NULL, strlen(strhex)/2+1);
+
+ ret_blob.length = strhex_to_str((char*)ret_blob.data,
+ strlen(strhex),
+ strhex);
+
+ return ret_blob;
+}
+
/**
* Routine to print a buffer as HEX digits, into an allocated string.
*/
int i;
char *hex_buffer;
- *out_hex_buffer = smb_xmalloc((len*2)+1);
+ *out_hex_buffer = SMB_XMALLOC_ARRAY(char, (len*2)+1);
hex_buffer = *out_hex_buffer;
for (i = 0; i < len; i++)
Check if a string is part of a list.
**/
-BOOL in_list(char *s,char *list,BOOL casesensitive)
+BOOL in_list(const char *s, const char *list, BOOL casesensitive)
{
pstring tok;
const char *p=list;
if (l == 0) {
if (!null_string) {
- if((null_string = (char *)malloc(1)) == NULL) {
+ if((null_string = (char *)SMB_MALLOC(1)) == NULL) {
DEBUG(0,("string_init: malloc fail for null_string.\n"));
return False;
}
}
*dest = null_string;
} else {
- (*dest) = strdup(src);
+ (*dest) = SMB_STRDUP(src);
if ((*dest) == NULL) {
DEBUG(0,("Out of memory in string_init\n"));
return False;
if (len == 0)
len = ls + 1; /* len is number of *bytes* */
- while (lp <= ls && (p = strstr(s,pattern))) {
+ while (lp <= ls && (p = strstr_m(s,pattern))) {
if (ls + (li-lp) >= len) {
DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
(int)(ls + (li-lp) - len),
s = string;
- in = strdup(insert);
+ in = SMB_STRDUP(insert);
if (!in) {
DEBUG(0, ("realloc_string_sub: out of memory!\n"));
return NULL;
}
}
- while ((p = strstr(s,pattern))) {
+ while ((p = strstr_m(s,pattern))) {
if (ld > 0) {
int offset = PTR_DIFF(s,string);
- char *t = Realloc(string, ls + ld + 1);
+ char *t = SMB_REALLOC(string, ls + ld + 1);
if (!t) {
DEBUG(0, ("realloc_string_sub: out of memory!\n"));
SAFE_FREE(in);
if (len == 0)
len = ls + 1; /* len is number of *bytes* */
- while (lp <= ls && (p = strstr(s,pattern))) {
+ while (lp <= ls && (p = strstr_m(s,pattern))) {
if (ls + (li-lp) >= len) {
DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
(int)(ls + (li-lp) - len),
}
}
- r = rp = (smb_ucs2_t *)malloc((lt + 1)*(sizeof(smb_ucs2_t)));
+ r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1);
if (!r) {
DEBUG(0, ("all_string_sub_w: out of memory!\n"));
return NULL;
smb_ucs2_t *p;
const char *s;
+ /* characters below 0x3F are guaranteed to not appear in
+ non-initial position in multi-byte charsets */
+ if ((c & 0xC0) == 0) {
+ return strchr(src, c);
+ }
+
/* 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
char *strrchr_m(const char *s, char c)
{
+ /* characters below 0x3F are guaranteed to not appear in
+ non-initial position in multi-byte charsets */
+ if ((c & 0xC0) == 0) {
+ return strrchr(s, c);
+ }
+
/* 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
return (char *)(s+strlen(s2));
}
+/***********************************************************************
+ strstr_m - We convert via ucs2 for now.
+***********************************************************************/
+
+char *strstr_m(const char *src, const char *findstr)
+{
+ smb_ucs2_t *p;
+ smb_ucs2_t *src_w, *find_w;
+ const char *s;
+ char *s2;
+ char *retp;
+
+ size_t findstr_len = 0;
+
+ /* for correctness */
+ if (!findstr[0]) {
+ return (char*)src;
+ }
+
+ /* Samba does single character findstr calls a *lot*. */
+ if (findstr[1] == '\0')
+ return strchr_m(src, *findstr);
+
+ /* 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) */
+
+ for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
+ if (*s == *findstr) {
+ if (!findstr_len)
+ findstr_len = strlen(findstr);
+
+ if (strncmp(s, findstr, findstr_len) == 0) {
+ return (char *)s;
+ }
+ }
+ }
+
+ if (!*s)
+ return NULL;
+
+#if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
+ /* 'make check' fails unless we do this */
+
+ /* With compose characters we must restart from the beginning. JRA. */
+ s = src;
+#endif
+
+ if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
+ DEBUG(0,("strstr_m: src malloc fail\n"));
+ return NULL;
+ }
+
+ if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
+ SAFE_FREE(src_w);
+ DEBUG(0,("strstr_m: find malloc fail\n"));
+ return NULL;
+ }
+
+ p = strstr_w(src_w, find_w);
+
+ if (!p) {
+ SAFE_FREE(src_w);
+ SAFE_FREE(find_w);
+ return NULL;
+ }
+
+ *p = 0;
+ if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
+ SAFE_FREE(src_w);
+ SAFE_FREE(find_w);
+ DEBUG(0,("strstr_m: dest malloc fail\n"));
+ return NULL;
+ }
+ retp = (char *)(s+strlen(s2));
+ SAFE_FREE(src_w);
+ SAFE_FREE(find_w);
+ SAFE_FREE(s2);
+ return retp;
+}
+
/**
Convert a string to lower case.
**/
void strlower_m(char *s)
{
+ size_t len;
+ int errno_save;
+
/* 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 (*s && !(((unsigned char)s[0]) & 0x7F)) {
+ while (*s && !(((unsigned char)s[0]) & 0x80)) {
*s = tolower((unsigned char)*s);
s++;
}
/* I assume that lowercased string takes the same number of bytes
* as source string even in UTF-8 encoding. (VIV) */
- unix_strlower(s,strlen(s)+1,s,strlen(s)+1);
+ len = strlen(s) + 1;
+ errno_save = errno;
+ errno = 0;
+ unix_strlower(s,len,s,len);
+ /* Catch mb conversion errors that may not terminate. */
+ if (errno)
+ s[len-1] = '\0';
+ errno = errno_save;
}
/**
void strupper_m(char *s)
{
+ size_t len;
+ int errno_save;
+
/* 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 (*s && !(((unsigned char)s[0]) & 0x7F)) {
+ while (*s && !(((unsigned char)s[0]) & 0x80)) {
*s = toupper((unsigned char)*s);
s++;
}
/* I assume that lowercased string takes the same number of bytes
* as source string even in multibyte encoding. (VIV) */
- unix_strupper(s,strlen(s)+1,s,strlen(s)+1);
+ len = strlen(s) + 1;
+ errno_save = errno;
+ errno = 0;
+ unix_strupper(s,len,s,len);
+ /* Catch mb conversion errors that may not terminate. */
+ if (errno)
+ s[len-1] = '\0';
+ errno = errno_save;
}
/**
char *s;
int i, j;
const char *hex = "0123456789ABCDEF";
- s = malloc(len * 3 + 1);
+ s = SMB_MALLOC(len * 3 + 1);
if (!s)
return NULL;
for (j=i=0;i<len;i++) {
}
-#ifndef HAVE_STRNDUP
+#if !defined(HAVE_STRNDUP) || defined(BROKEN_STRNDUP)
/**
Some platforms don't have strndup.
**/
+#if defined(PARANOID_MALLOC_CHECKER)
+#undef strndup
+#endif
char *strndup(const char *s, size_t n)
{
char *ret;
n = strnlen(s, n);
- ret = malloc(n+1);
+ ret = SMB_MALLOC(n+1);
if (!ret)
return NULL;
memcpy(ret, s, n);
return ret;
}
+
+#if defined(PARANOID_MALLOC_CHECKER)
+#define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
#endif
-#ifndef HAVE_STRNLEN
+#endif
+
+#if !defined(HAVE_STRNLEN) || defined(BROKEN_STRNLEN)
/**
Some platforms don't have strnlen
**/
size_t strnlen(const char *s, size_t n)
{
- int i;
- for (i=0; s[i] && i<n; i++)
+ size_t i;
+ for (i=0; i<n && s[i] != '\0'; i++)
/* noop */ ;
return i;
}
if (!string || !*string)
return NULL;
- s = strdup(string);
+ s = SMB_STRDUP(string);
if (!s) {
DEBUG(0,("str_list_make: Unable to allocate memory"));
return NULL;
while (next_token(&str, tok, sep, sizeof(tok))) {
if (num == lsize) {
lsize += S_LIST_ABS;
- rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
+ rlist = SMB_REALLOC_ARRAY(list, char *, lsize +1);
if (!rlist) {
DEBUG(0,("str_list_make: Unable to allocate memory"));
str_list_free(&list);
memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
}
- list[num] = strdup(tok);
+ list[num] = SMB_STRDUP(tok);
if (!list[num]) {
DEBUG(0,("str_list_make: Unable to allocate memory"));
str_list_free(&list);
while (src[num]) {
if (num == lsize) {
lsize += S_LIST_ABS;
- rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
+ rlist = SMB_REALLOC_ARRAY(list, char *, lsize +1);
if (!rlist) {
DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
str_list_free(&list);
memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
}
- list[num] = strdup(src[num]);
+ list[num] = SMB_STRDUP(src[num]);
if (!list[num]) {
DEBUG(0,("str_list_copy: Unable to allocate memory"));
str_list_free(&list);
SAFE_FREE(*list);
}
+/******************************************************************************
+ *****************************************************************************/
+
+int str_list_count( const char **list )
+{
+ int i = 0;
+
+ /* count the number of list members */
+
+ for ( i=0; *list; i++, list++ );
+
+ return i;
+}
+
/******************************************************************************
version of standard_sub_basic() for string lists; uses alloc_sub_basic()
for the work
return False;
}
+ SAFE_FREE(*list);
*list = tmpstr;
list++;
s = *list;
ls = (ssize_t)strlen(s);
- while ((p = strstr(s, pattern))) {
+ while ((p = strstr_m(s, pattern))) {
t = *list;
d = p -t;
if (ld) {
- t = (char *) malloc(ls +ld +1);
+ t = (char *) SMB_MALLOC(ls +ld +1);
if (!t) {
DEBUG(0,("str_list_substitute: Unable to allocate memory"));
return False;
return 0;
count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
- if ( (*ip_list = (struct ip_service*)malloc(count * sizeof(struct ip_service))) == NULL ) {
+ if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
return 0;
}
{
char *p=buf;
- while ((p=strchr_m(p,'+')))
- *p = ' ';
-
- p = buf;
-
while (p && *p && (p=strchr_m(p,'%'))) {
int c1 = p[1];
int c2 = p[2];
s++; i++;
}
+ if ((n > 0) && (*s == '=')) {
+ n -= 1;
+ }
+
/* fix up length */
decoded.length = n;
return decoded;
void base64_decode_inplace(char *s)
{
DATA_BLOB decoded = base64_decode_data_blob(s);
- memcpy(s, decoded.data, decoded.length);
- /* null terminate */
- s[decoded.length] = '\0';
+
+ if ( decoded.length != 0 ) {
+ memcpy(s, decoded.data, decoded.length);
+
+ /* null terminate */
+ s[decoded.length] = '\0';
+ } else {
+ *s = '\0';
+ }
data_blob_free(&decoded);
}
{
int bits = 0;
int char_count = 0;
- size_t out_cnt = 0;
- size_t len = data.length;
- size_t output_len = data.length * 2;
- char *result = malloc(output_len); /* get us plenty of space */
+ size_t out_cnt, len, output_len;
+ char *result;
+
+ if (!data.length || !data.data)
+ return NULL;
+
+ out_cnt = 0;
+ len = data.length;
+ output_len = data.length * 2;
+ result = SMB_MALLOC(output_len); /* get us plenty of space */
while (len-- && out_cnt < (data.length * 2) - 5) {
int c = (unsigned char) *(data.data++);
return val;
}
+
+void string_append(char **left, const char *right)
+{
+ int new_len = strlen(right) + 1;
+
+ if (*left == NULL) {
+ *left = SMB_MALLOC(new_len);
+ *left[0] = '\0';
+ } else {
+ new_len += strlen(*left);
+ *left = SMB_REALLOC(*left, new_len);
+ }
+
+ if (*left == NULL)
+ return;
+
+ safe_strcat(*left, right, new_len-1);
+}
+
+BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
+ const char *str, const char ***strings,
+ int *num)
+{
+ char *dup_str = talloc_strdup(mem_ctx, str);
+
+ *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings, const char *, (*num)+1);
+
+ if ((*strings == NULL) || (dup_str == NULL))
+ return False;
+
+ (*strings)[*num] = dup_str;
+ *num += 1;
+ return True;
+}
+
+/* Append an sprintf'ed string. Double buffer size on demand. Usable without
+ * error checking in between. The indiation that something weird happened is
+ * string==NULL */
+
+void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
+ size_t *bufsize, const char *fmt, ...)
+{
+ va_list ap;
+ char *newstr;
+ int ret;
+ BOOL increased;
+
+ /* len<0 is an internal marker that something failed */
+ if (*len < 0)
+ goto error;
+
+ if (*string == NULL) {
+ if (*bufsize == 0)
+ *bufsize = 128;
+
+ if (mem_ctx != NULL)
+ *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
+ else
+ *string = SMB_MALLOC_ARRAY(char, *bufsize);
+
+ if (*string == NULL)
+ goto error;
+ }
+
+ va_start(ap, fmt);
+ ret = vasprintf(&newstr, fmt, ap);
+ va_end(ap);
+
+ if (ret < 0)
+ goto error;
+
+ increased = False;
+
+ while ((*len)+ret >= *bufsize) {
+ increased = True;
+ *bufsize *= 2;
+ if (*bufsize >= (1024*1024*256))
+ goto error;
+ }
+
+ if (increased) {
+ if (mem_ctx != NULL)
+ *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
+ *bufsize);
+ else
+ *string = SMB_REALLOC_ARRAY(*string, char, *bufsize);
+
+ if (*string == NULL)
+ goto error;
+ }
+
+ StrnCpy((*string)+(*len), newstr, ret);
+ (*len) += ret;
+ free(newstr);
+ return;
+
+ error:
+ *len = -1;
+ *string = NULL;
+}