X-Git-Url: http://git.samba.org/?a=blobdiff_plain;f=source3%2Flib%2Futil_unistr.c;h=e8483d32c678afd6b3eeb90b4ac61242e87f5208;hb=403ddeb5d8832ab14cbcf3e77d108cefb8386149;hp=45f09da85bc63b8225287a8ff5bbfcdc676f747f;hpb=64b54e534008a1ac36b9ba21726ca0954fe00d63;p=samba.git diff --git a/source3/lib/util_unistr.c b/source3/lib/util_unistr.c index 45f09da85bc..e8483d32c67 100644 --- a/source3/lib/util_unistr.c +++ b/source3/lib/util_unistr.c @@ -33,14 +33,7 @@ static uint8 *valid_table; static bool upcase_table_use_unmap; static bool lowcase_table_use_unmap; static bool valid_table_use_unmap; - -/** - * This table says which Unicode characters are valid dos - * characters. - * - * Each value is just a single bit. - **/ -static uint8 doschar_table[8192]; /* 65536 characters / 8 bits/byte */ +static bool initialized; /** * Destroy global objects allocated by load_case_tables() @@ -52,6 +45,7 @@ void gfree_case_tables(void) unmap_file(upcase_table, 0x20000); else SAFE_FREE(upcase_table); + upcase_table = NULL; } if ( lowcase_table ) { @@ -59,6 +53,7 @@ void gfree_case_tables(void) unmap_file(lowcase_table, 0x20000); else SAFE_FREE(lowcase_table); + lowcase_table = NULL; } if ( valid_table ) { @@ -66,7 +61,9 @@ void gfree_case_tables(void) unmap_file(valid_table, 0x10000); else SAFE_FREE(valid_table); + valid_table = NULL; } + initialized = false; } /** @@ -78,15 +75,14 @@ void gfree_case_tables(void) void load_case_tables(void) { - static int initialised; char *old_locale = NULL, *saved_locale = NULL; int i; TALLOC_CTX *frame = NULL; - if (initialised) { + if (initialized) { return; } - initialised = 1; + initialized = true; frame = talloc_stackframe(); @@ -153,21 +149,6 @@ void load_case_tables(void) TALLOC_FREE(frame); } -/* - see if a ucs2 character can be mapped correctly to a dos character - and mapped back to the same character in ucs2 -*/ - -int check_dos_char(smb_ucs2_t c) -{ - lazy_initialize_conv(); - - /* Find the right byte, and right bit within the byte; return - * 1 or 0 */ - return (doschar_table[(c & 0xffff) / 8] & (1 << (c & 7))) != 0; -} - - static int check_dos_char_slowly(smb_ucs2_t c) { char buf[10]; @@ -185,33 +166,6 @@ static int check_dos_char_slowly(smb_ucs2_t c) return (c == c2); } - -/** - * Fill out doschar table the hard way, by examining each character - **/ - -void init_doschar_table(void) -{ - int i, j, byteval; - - /* For each byte of packed table */ - - for (i = 0; i <= 0xffff; i += 8) { - byteval = 0; - for (j = 0; j <= 7; j++) { - smb_ucs2_t c; - - c = i + j; - - if (check_dos_char_slowly(c)) { - byteval |= 1 << j; - } - } - doschar_table[i/8] = byteval; - } -} - - /** * Load the valid character map table from valid.dat or * create from the configured codepage. @@ -245,22 +199,24 @@ void init_valid_table(void) * It might need to be regenerated if the code page changed. * We know that we're not using a mapped file, so we can * free() the old one. */ - if (valid_table) - SAFE_FREE(valid_table); + SAFE_FREE(valid_table); /* use free rather than unmap */ valid_table_use_unmap = False; DEBUG(2,("creating default valid table\n")); valid_table = (uint8 *)SMB_MALLOC(0x10000); + SMB_ASSERT(valid_table != NULL); for (i=0;i<128;i++) { valid_table[i] = isalnum(i) || strchr(allowed,i); } - + + lazy_initialize_conv(); + for (;i<0x10000;i++) { smb_ucs2_t c; SSVAL(&c, 0, i); - valid_table[i] = check_dos_char(c); + valid_table[i] = check_dos_char_slowly(c); } } @@ -303,101 +259,6 @@ char *skip_unibuf(char *src, size_t len) return src; } -/* Copy a string from little-endian or big-endian unicode source (depending - * on flags) to internal samba format destination - */ - -int rpcstr_pull(char* dest, void *src, int dest_len, int src_len, int flags) -{ - if (!src) { - dest[0] = 0; - return 0; - } - if(dest_len==-1) { - dest_len=MAXUNI-3; - } - return pull_ucs2(NULL, dest, src, dest_len, src_len, flags|STR_UNICODE|STR_NOALIGN); -} - -/* Copy a string from little-endian or big-endian unicode source (depending - * on flags) to internal samba format destination. Allocates on talloc ctx. - */ - -int rpcstr_pull_talloc(TALLOC_CTX *ctx, - char **dest, - void *src, - int src_len, - int flags) -{ - return pull_ucs2_base_talloc(ctx, - NULL, - dest, - src, - src_len, - flags|STR_UNICODE|STR_NOALIGN); - -} - -/* Copy a string from a unistr2 source to internal samba format - destination. Use this instead of direct calls to rpcstr_pull() to avoid - having to determine whether the source string is null terminated. */ - -int rpcstr_pull_unistr2_fstring(char *dest, UNISTR2 *src) -{ - return pull_ucs2(NULL, dest, src->buffer, sizeof(fstring), - src->uni_str_len * 2, 0); -} - -/* Helper function to return a talloc'ed string. I have implemented it with a - * copy because I don't really know how pull_ucs2 and friends calculate the - * target size. If this turns out to be a major bottleneck someone with deeper - * multi-byte knowledge needs to revisit this. - * I just did (JRA :-). No longer uses copy. - * My (VL) use is dsr_getdcname, which returns 6 strings, the alternative would - * have been to manually talloc_strdup them in rpc_client/cli_netlogon.c. - */ - -char *rpcstr_pull_unistr2_talloc(TALLOC_CTX *ctx, const UNISTR2 *src) -{ - char *dest = NULL; - size_t dest_len = convert_string_talloc(ctx, - CH_UTF16LE, - CH_UNIX, - src->buffer, - src->uni_str_len * 2, - (void **)&dest, - true); - if (dest_len == (size_t)-1) { - return NULL; - } - - /* Ensure we're returning a null terminated string. */ - if (dest_len) { - /* Did we already process the terminating zero ? */ - if (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 NULL; - } - } - /* Yay - space ! */ - dest[dest_len] = '\0'; - dest_len++; - } - } else if (dest) { - dest[0] = 0; - } - - return dest; -} - /* Converts a string from internal samba format to unicode */ @@ -408,86 +269,15 @@ int rpcstr_push(void *dest, const char *src, size_t dest_len, int flags) /* Converts a string from internal samba format to unicode. Always terminates. * Actually just a wrapper round push_ucs2_talloc(). - */ + */ int rpcstr_push_talloc(TALLOC_CTX *ctx, smb_ucs2_t **dest, const char *src) { - return push_ucs2_talloc(ctx, dest, src); -} - -/******************************************************************* - Convert a (little-endian) UNISTR2 structure to an ASCII string. -********************************************************************/ - -void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen) -{ - if ((str == NULL) || (str->uni_str_len == 0)) { - *dest='\0'; - return; - } - pull_ucs2(NULL, dest, str->buffer, maxlen, str->uni_str_len*2, STR_NOALIGN); -} - -/******************************************************************* - Convert a (little-endian) UNISTR3 structure to an ASCII string. -********************************************************************/ - -void unistr3_to_ascii(char *dest, const UNISTR3 *str, size_t maxlen) -{ - if ((str == NULL) || (str->uni_str_len == 0)) { - *dest='\0'; - return; - } - pull_ucs2(NULL, dest, str->str.buffer, maxlen, str->uni_str_len*2, - STR_NOALIGN); -} - -/******************************************************************* - Return a string for displaying a UNISTR2. Guarentees to return a - valid string - "" if nothing else. - Changed to use talloc_tos() under the covers.... JRA. -********************************************************************/ - -const char *unistr2_static(const UNISTR2 *str) -{ - size_t ret = (size_t)-1; - char *dest = NULL; - - if ((str == NULL) || (str->uni_str_len == 0)) { - return ""; - } - - ret = pull_ucs2_base_talloc(talloc_tos(), - NULL, - &dest, - str->buffer, - str->uni_str_len*2, - STR_NOALIGN); - if (ret == (size_t)-1 || dest == NULL) { - return ""; - } - - return dest; -} - -/******************************************************************* - Duplicate a UNISTR2 string into a null terminated char* - using a talloc context. -********************************************************************/ - -char *unistr2_tdup(TALLOC_CTX *ctx, const UNISTR2 *str) -{ - char *s; - int maxlen = (str->uni_str_len+1)*4; - if (!str->buffer) { - return NULL; - } - s = (char *)TALLOC(ctx, maxlen); /* convervative */ - if (!s) { - return NULL; - } - pull_ucs2(NULL, s, str->buffer, maxlen, str->uni_str_len*2, STR_NOALIGN); - return s; + size_t size; + if (push_ucs2_talloc(ctx, dest, src, &size)) + return size; + else + return -1; } /******************************************************************* @@ -1028,89 +818,6 @@ smb_ucs2_t *strstr_wa(const smb_ucs2_t *s, const char *ins) return NULL; } -/******************************************************************* - Returns the length in number of wide characters. -******************************************************************/ - -int unistrlen(uint16 *s) -{ - int len; - - if (!s) { - return -1; - } - - for (len=0; SVAL(s,0); s++,len++) { - ; - } - - return len; -} - -/******************************************************************* - Strcpy for unicode strings. Returns length (in num of wide chars). - Not odd align safe. -********************************************************************/ - -int unistrcpy(uint16 *dst, uint16 *src) -{ - int num_wchars = 0; - - while (SVAL(src,0)) { - *dst++ = *src++; - num_wchars++; - } - *dst = 0; - - return num_wchars; -} - -/** - * Samba ucs2 type to UNISTR2 conversion - * - * @param ctx Talloc context to create the dst strcture (if null) and the - * contents of the unicode string. - * @param dst UNISTR2 destination. If equals null, then it's allocated. - * @param src smb_ucs2_t source. - * @param max_len maximum number of unicode characters to copy. If equals - * null, then null-termination of src is taken - * - * @return copied UNISTR2 destination - **/ - -UNISTR2* ucs2_to_unistr2(TALLOC_CTX *ctx, UNISTR2* dst, smb_ucs2_t* src) -{ - size_t len; - - if (!src) { - return NULL; - } - - len = strlen_w(src); - - /* allocate UNISTR2 destination if not given */ - if (!dst) { - dst = TALLOC_P(ctx, UNISTR2); - if (!dst) - return NULL; - } - if (!dst->buffer) { - dst->buffer = TALLOC_ARRAY(ctx, uint16, len + 1); - if (!dst->buffer) - return NULL; - } - - /* set UNISTR2 parameters */ - dst->uni_max_len = len + 1; - dst->offset = 0; - dst->uni_str_len = len; - - /* copy the actual unicode string */ - strncpy_w(dst->buffer, src, dst->uni_max_len); - - return dst; -} - /************************************************************* ascii only toupper - saves the need for smbd to be in C locale. *************************************************************/