Fix bug #9455 munmap called for an address location not mapped by samba.
[samba.git] / source3 / lib / util_unistr.c
index 45f09da85bc63b8225287a8ff5bbfcdc676f747f..e8483d32c678afd6b3eeb90b4ac61242e87f5208 100644 (file)
@@ -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 <tt>valid.dat</tt> 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.
 *************************************************************/