X-Git-Url: http://git.samba.org/?a=blobdiff_plain;f=source3%2Flib%2Futil_str.c;h=17a4a8f2c4e9727f56a0c559d70de14ac4c14c57;hb=157b88da4db727eafa682c7fc7eab11d5955f57b;hp=fde4f825e81416b45ade0b5f08ff7b5eef19f7cf;hpb=4f2635b729e636e123afacb0970c3d49343b3e90;p=samba.git diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index fde4f825e81..17a4a8f2c4e 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -24,7 +24,7 @@ #include "includes.h" -char toupper_ascii_fast_table[128] = { +const char toupper_ascii_fast_table[128] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, @@ -35,118 +35,6 @@ char toupper_ascii_fast_table[128] = { 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f }; -/** - * @file - * @brief String utilities. - **/ - -static bool next_token_internal_talloc(TALLOC_CTX *ctx, - const char **ptr, - char **pp_buff, - const char *sep, - bool ltrim) -{ - char *s; - char *saved_s; - char *pbuf; - bool quoted; - size_t len=1; - - *pp_buff = NULL; - if (!ptr) { - return(false); - } - - s = (char *)*ptr; - - /* default to simple separators */ - if (!sep) { - sep = " \t\n\r"; - } - - /* find the first non sep char, if left-trimming is requested */ - if (ltrim) { - while (*s && strchr_m(sep,*s)) { - s++; - } - } - - /* nothing left? */ - if (!*s) { - return false; - } - - /* When restarting we need to go from here. */ - saved_s = s; - - /* Work out the length needed. */ - for (quoted = false; *s && - (quoted || !strchr_m(sep,*s)); s++) { - if (*s == '\"') { - quoted = !quoted; - } else { - len++; - } - } - - /* We started with len = 1 so we have space for the nul. */ - *pp_buff = TALLOC_ARRAY(ctx, char, len); - if (!*pp_buff) { - return false; - } - - /* copy over the token */ - pbuf = *pp_buff; - s = saved_s; - for (quoted = false; *s && - (quoted || !strchr_m(sep,*s)); s++) { - if ( *s == '\"' ) { - quoted = !quoted; - } else { - *pbuf++ = *s; - } - } - - *ptr = (*s) ? s+1 : s; - *pbuf = 0; - - return true; -} - -#if 0 -/* - * Get the next token from a string, return false if none found. Handles - * double-quotes. This version trims leading separator characters before - * looking for a token. - */ -bool next_token(const char **ptr, char *buff, const char *sep, size_t bufsize) -{ - return next_token_internal(ptr, buff, sep, bufsize, true); -} -#endif - -bool next_token_talloc(TALLOC_CTX *ctx, - const char **ptr, - char **pp_buff, - const char *sep) -{ - return next_token_internal_talloc(ctx, ptr, pp_buff, sep, true); -} - -/* - * Get the next token from a string, return false if none found. Handles - * double-quotes. This version does not trim leading separator characters - * before looking for a token. - */ - -bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx, - const char **ptr, - char **pp_buff, - const char *sep) -{ - return next_token_internal_talloc(ctx, ptr, pp_buff, sep, false); -} - /** * Case insensitive string compararison. * @@ -208,15 +96,15 @@ int StrCaseCmp(const char *s, const char *t) return +1; } - if (!push_ucs2_allocate(&buffer_s, ps, &size)) { + if (!push_ucs2_talloc(talloc_tos(), &buffer_s, ps, &size)) { return strcmp(ps, pt); /* 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(&buffer_t, pt, &size)) { - SAFE_FREE(buffer_s); + if (!push_ucs2_talloc(talloc_tos(), &buffer_t, pt, &size)) { + TALLOC_FREE(buffer_s); return strcmp(ps, pt); /* Not quite the right answer, but finding the right one under this failure case is expensive, and it's pretty @@ -224,8 +112,8 @@ int StrCaseCmp(const char *s, const char *t) } ret = strcasecmp_w(buffer_s, buffer_t); - SAFE_FREE(buffer_s); - SAFE_FREE(buffer_t); + TALLOC_FREE(buffer_s); + TALLOC_FREE(buffer_t); return ret; } @@ -269,15 +157,15 @@ int StrnCaseCmp(const char *s, const char *t, size_t len) return 0; } - if (!push_ucs2_allocate(&buffer_s, ps, &size)) { + if (!push_ucs2_talloc(talloc_tos(), &buffer_s, ps, &size)) { 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 */ } - if (!push_ucs2_allocate(&buffer_t, pt, &size)) { - SAFE_FREE(buffer_s); + if (!push_ucs2_talloc(talloc_tos(), &buffer_t, pt, &size)) { + TALLOC_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, @@ -285,8 +173,8 @@ int StrnCaseCmp(const char *s, const char *t, size_t len) } ret = strncasecmp_w(buffer_s, buffer_t, len-n); - SAFE_FREE(buffer_s); - SAFE_FREE(buffer_t); + TALLOC_FREE(buffer_s); + TALLOC_FREE(buffer_t); return ret; } @@ -478,11 +366,11 @@ size_t str_charnum(const char *s) { size_t ret, converted_size; smb_ucs2_t *tmpbuf2 = NULL; - if (!push_ucs2_allocate(&tmpbuf2, s, &converted_size)) { + if (!push_ucs2_talloc(talloc_tos(), &tmpbuf2, s, &converted_size)) { return 0; } ret = strlen_w(tmpbuf2); - SAFE_FREE(tmpbuf2); + TALLOC_FREE(tmpbuf2); return ret; } @@ -496,11 +384,11 @@ size_t str_ascii_charnum(const char *s) { size_t ret, converted_size; char *tmpbuf2 = NULL; - if (!push_ascii_allocate(&tmpbuf2, s, &converted_size)) { + if (!push_ascii_talloc(talloc_tos(), &tmpbuf2, s, &converted_size)) { return 0; } ret = strlen(tmpbuf2); - SAFE_FREE(tmpbuf2); + TALLOC_FREE(tmpbuf2); return ret; } @@ -567,7 +455,7 @@ bool strhasupper(const char *s) bool ret; size_t converted_size; - if (!push_ucs2_allocate(&tmp, s, &converted_size)) { + if (!push_ucs2_talloc(talloc_tos(), &tmp, s, &converted_size)) { return false; } @@ -578,7 +466,7 @@ bool strhasupper(const char *s) } ret = (*p != 0); - SAFE_FREE(tmp); + TALLOC_FREE(tmp); return ret; } @@ -592,7 +480,7 @@ bool strhaslower(const char *s) bool ret; size_t converted_size; - if (!push_ucs2_allocate(&tmp, s, &converted_size)) { + if (!push_ucs2_talloc(talloc_tos(), &tmp, s, &converted_size)) { return false; } @@ -603,7 +491,7 @@ bool strhaslower(const char *s) } ret = (*p != 0); - SAFE_FREE(tmp); + TALLOC_FREE(tmp); return ret; } @@ -698,7 +586,9 @@ char *safe_strcat_fn(const char *fn, Paranoid strcpy into a buffer of given length (includes terminating zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars and replaces with '_'. Deliberately does *NOT* check for multibyte - characters. Don't change it ! + characters. Treats src as an array of bytes, not as a multibyte + string. Any byte >0x7f is automatically converted to '_'. + other_safe_chars must also contain an ascii string (bytes<0x7f). **/ char *alpha_strcpy_fn(const char *fn, @@ -734,8 +624,12 @@ char *alpha_strcpy_fn(const char *fn, for(i = 0; i < len; i++) { int val = (src[i] & 0xff); - if (isupper_ascii(val) || islower_ascii(val) || - isdigit(val) || strchr_m(other_safe_chars, val)) + if (val > 0x7f) { + dest[i] = '_'; + continue; + } + if (isupper(val) || islower(val) || + isdigit(val) || strchr(other_safe_chars, val)) dest[i] = src[i]; else dest[i] = '_'; @@ -1289,24 +1183,24 @@ char *strchr_m(const char *src, char c) s = src; #endif - if (!push_ucs2_allocate(&ws, s, &converted_size)) { + if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) { /* Wrong answer, but what can we do... */ return strchr(src, c); } p = strchr_w(ws, UCS2_CHAR(c)); if (!p) { - SAFE_FREE(ws); + TALLOC_FREE(ws); return NULL; } *p = 0; - if (!pull_ucs2_allocate(&s2, ws, &converted_size)) { + if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) { 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); + TALLOC_FREE(ws); + TALLOC_FREE(s2); return ret; } @@ -1360,24 +1254,24 @@ char *strrchr_m(const char *s, char c) char *ret; size_t converted_size; - if (!push_ucs2_allocate(&ws, s, &converted_size)) { + if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) { /* Wrong answer, but what can we do. */ return strrchr(s, c); } p = strrchr_w(ws, UCS2_CHAR(c)); if (!p) { - SAFE_FREE(ws); + TALLOC_FREE(ws); return NULL; } *p = 0; - if (!pull_ucs2_allocate(&s2, ws, &converted_size)) { - SAFE_FREE(ws); + if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) { + TALLOC_FREE(ws); /* Wrong answer, but what can we do. */ return strrchr(s, c); } ret = (char *)(s+strlen(s2)); - SAFE_FREE(ws); - SAFE_FREE(s2); + TALLOC_FREE(ws); + TALLOC_FREE(s2); return ret; } } @@ -1395,24 +1289,24 @@ char *strnrchr_m(const char *s, char c, unsigned int n) char *ret; size_t converted_size; - if (!push_ucs2_allocate(&ws, s, &converted_size)) { + if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) { /* Too hard to try and get right. */ return NULL; } p = strnrchr_w(ws, UCS2_CHAR(c), n); if (!p) { - SAFE_FREE(ws); + TALLOC_FREE(ws); return NULL; } *p = 0; - if (!pull_ucs2_allocate(&s2, ws, &converted_size)) { - SAFE_FREE(ws); + if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) { + TALLOC_FREE(ws); /* Too hard to try and get right. */ return NULL; } ret = (char *)(s+strlen(s2)); - SAFE_FREE(ws); - SAFE_FREE(s2); + TALLOC_FREE(ws); + TALLOC_FREE(s2); return ret; } @@ -1464,13 +1358,13 @@ char *strstr_m(const char *src, const char *findstr) s = src; #endif - if (!push_ucs2_allocate(&src_w, src, &converted_size)) { + if (!push_ucs2_talloc(talloc_tos(), &src_w, src, &converted_size)) { DEBUG(0,("strstr_m: src malloc fail\n")); return NULL; } - if (!push_ucs2_allocate(&find_w, findstr, &converted_size)) { - SAFE_FREE(src_w); + if (!push_ucs2_talloc(talloc_tos(), &find_w, findstr, &converted_size)) { + TALLOC_FREE(src_w); DEBUG(0,("strstr_m: find malloc fail\n")); return NULL; } @@ -1478,22 +1372,22 @@ char *strstr_m(const char *src, const char *findstr) p = strstr_w(src_w, find_w); if (!p) { - SAFE_FREE(src_w); - SAFE_FREE(find_w); + TALLOC_FREE(src_w); + TALLOC_FREE(find_w); return NULL; } *p = 0; - if (!pull_ucs2_allocate(&s2, src_w, &converted_size)) { - SAFE_FREE(src_w); - SAFE_FREE(find_w); + if (!pull_ucs2_talloc(talloc_tos(), &s2, src_w, &converted_size)) { + TALLOC_FREE(src_w); + TALLOC_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); + TALLOC_FREE(src_w); + TALLOC_FREE(find_w); + TALLOC_FREE(s2); return retp; } @@ -1566,12 +1460,12 @@ void strupper_m(char *s) } /** - Count the number of UCS2 characters in a string. Normally this will - be the same as the number of bytes in a string for single byte strings, - but will be different for multibyte. -**/ - -size_t strlen_m(const char *s) + * Calculate the number of units (8 or 16-bit, depending on the + * destination charset), that would be needed to convert the input + * string which is expected to be in in CH_UNIX encoding to the + * destination charset (which should be a unicode charset). + */ +size_t strlen_m_ext(const char *s, const charset_t dst_charset) { size_t count = 0; @@ -1591,19 +1485,67 @@ size_t strlen_m(const char *s) while (*s) { size_t c_size; codepoint_t c = next_codepoint(s, &c_size); - if (c < 0x10000) { - /* Unicode char fits into 16 bits. */ + s += c_size; + + switch(dst_charset) { + case CH_UTF16LE: + case CH_UTF16BE: + case CH_UTF16MUNGED: + if (c < 0x10000) { + /* Unicode char fits into 16 bits. */ + count += 1; + } else { + /* Double-width unicode char - 32 bits. */ + count += 2; + } + break; + case CH_UTF8: + /* + * this only checks ranges, and does not + * check for invalid codepoints + */ + if (c < 0x80) { + count += 1; + } else if (c < 0x800) { + count += 2; + } else if (c < 0x1000) { + count += 3; + } else { + count += 4; + } + break; + default: + /* + * non-unicode encoding: + * assume that each codepoint fits into + * one unit in the destination encoding. + */ count += 1; - } else { - /* Double-width unicode char - 32 bits. */ - count += 2; } - s += c_size; } return count; } +size_t strlen_m_ext_term(const char *s, const charset_t dst_charset) +{ + if (!s) { + return 0; + } + return strlen_m_ext(s, dst_charset) + 1; +} + +/** + Count the number of UCS2 characters in a string. Normally this will + be the same as the number of bytes in a string for single byte strings, + but will be different for multibyte. +**/ + +size_t strlen_m(const char *s) +{ + return strlen_m_ext(s, CH_UTF16LE); +} + /** Count the number of UCS2 characters in a string including the null terminator. @@ -1641,14 +1583,15 @@ size_t strlen_m_term_null(const char *s) Caller must free. **/ -char *binary_string_rfc2254(char *buf, int len) +char *binary_string_rfc2254(TALLOC_CTX *mem_ctx, const uint8_t *buf, int len) { char *s; int i, j; const char *hex = "0123456789ABCDEF"; - s = (char *)SMB_MALLOC(len * 3 + 1); - if (!s) + s = talloc_array(mem_ctx, char, len * 3 + 1); + if (s == NULL) { return NULL; + } for (j=i=0;i> 4]; @@ -1727,7 +1670,7 @@ bool str_list_sub_basic( char **list, const char *smb_name, } /****************************************************************************** - substritute a specific pattern in a string list + substitute a specific pattern in a string list *****************************************************************************/ bool str_list_substitute(char **list, const char *pattern, const char *insert) @@ -2043,7 +1986,7 @@ char *base64_encode_data_blob(TALLOC_CTX *mem_ctx, DATA_BLOB data) result = TALLOC_ARRAY(mem_ctx, char, output_len); /* get us plenty of space */ SMB_ASSERT(result != NULL); - while (len-- && out_cnt < (data.length * 2) - 5) { + while (len--) { int c = (unsigned char) *(data.data++); bits += c; char_count++; @@ -2358,6 +2301,10 @@ bool validate_net_name( const char *name, { int i; + if (!name) { + return false; + } + for ( i=0; i