Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/lib/charcnv.c

    r871 r988  
    2323#include "includes.h"
    2424
    25 /* We can parameterize this if someone complains.... JRA. */
    26 
    27 char lp_failed_convert_char(void)
    28 {
    29         return '_';
    30 }
    31 
    32 /**
    33  * @file
    34  *
    35  * @brief Character-set conversion routines built on our iconv.
    36  *
    37  * @note Samba's internal character set (at least in the 3.0 series)
    38  * is always the same as the one for the Unix filesystem.  It is
    39  * <b>not</b> necessarily UTF-8 and may be different on machines that
    40  * need i18n filenames to be compatible with Unix software.  It does
    41  * have to be a superset of ASCII.  All multibyte sequences must start
    42  * with a byte with the high bit set.
    43  *
    44  * @sa lib/iconv.c
    45  */
    46 
    47 
    48 static bool conv_silent; /* Should we do a debug if the conversion fails ? */
    49 static bool initialized;
    50 
    51 void lazy_initialize_conv(void)
    52 {
    53         if (!initialized) {
    54                 load_case_tables_library();
    55                 init_iconv();
    56                 initialized = true;
    57         }
    58 }
    59 
    6025/**
    6126 * Destroy global objects allocated by init_iconv()
     
    6328void gfree_charcnv(void)
    6429{
    65         TALLOC_FREE(global_iconv_convenience);
    66         initialized = false;
    67 }
    68 
    69 /**
    70  * Initialize iconv conversion descriptors.
    71  *
    72  * This is called the first time it is needed, and also called again
    73  * every time the configuration is reloaded, because the charset or
    74  * codepage might have changed.
    75  **/
    76 void init_iconv(void)
    77 {
    78         global_iconv_convenience = smb_iconv_convenience_reinit(NULL, lp_dos_charset(),
    79                                                                 lp_unix_charset(), lp_display_charset(),
    80                                                                 true, global_iconv_convenience);
    81 }
    82 
    83 /**
    84  * Convert string from one encoding to another, making error checking etc
    85  * Slow path version - uses (slow) iconv.
    86  *
    87  * @param src pointer to source string (multibyte or singlebyte)
    88  * @param srclen length of the source string in bytes
    89  * @param dest pointer to destination string (multibyte or singlebyte)
    90  * @param destlen maximal length allowed for string
    91  * @param allow_bad_conv determines if a "best effort" conversion is acceptable (never returns errors)
    92  * @returns the number of bytes occupied in the destination
    93  *
    94  * Ensure the srclen contains the terminating zero.
    95  *
    96  **/
    97 
    98 static size_t convert_string_internal(charset_t from, charset_t to,
    99                       void const *src, size_t srclen,
    100                       void *dest, size_t destlen, bool allow_bad_conv)
    101 {
    102         size_t i_len, o_len;
    103         size_t retval;
    104         const char* inbuf = (const char*)src;
    105         char* outbuf = (char*)dest;
    106         smb_iconv_t descriptor;
    107         struct smb_iconv_convenience *ic;
    108 
    109         lazy_initialize_conv();
    110         ic = get_iconv_convenience();
    111         descriptor = get_conv_handle(ic, from, to);
    112 
    113         if (srclen == (size_t)-1) {
    114                 if (from == CH_UTF16LE || from == CH_UTF16BE) {
    115                         srclen = (strlen_w((const smb_ucs2_t *)src)+1) * 2;
    116                 } else {
    117                         srclen = strlen((const char *)src)+1;
    118                 }
    119         }
    120 
    121 
    122         if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
    123                 if (!conv_silent)
    124                         DEBUG(0,("convert_string_internal: Conversion not supported.\n"));
    125                 return (size_t)-1;
    126         }
    127 
    128         i_len=srclen;
    129         o_len=destlen;
    130 
    131  again:
    132 
    133         retval = smb_iconv(descriptor, &inbuf, &i_len, &outbuf, &o_len);
    134         if(retval==(size_t)-1) {
    135                 const char *reason="unknown error";
    136                 switch(errno) {
    137                         case EINVAL:
    138                                 reason="Incomplete multibyte sequence";
    139                                 if (!conv_silent)
    140                                         DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",reason,inbuf));
    141                                 if (allow_bad_conv)
    142                                         goto use_as_is;
    143                                 return (size_t)-1;
    144                         case E2BIG:
    145                                 reason="No more room";
    146                                 if (!conv_silent) {
    147                                         if (from == CH_UNIX) {
    148                                                 DEBUG(3,("E2BIG: convert_string(%s,%s): srclen=%u destlen=%u - '%s'\n",
    149                                                          charset_name(ic, from), charset_name(ic, to),
    150                                                         (unsigned int)srclen, (unsigned int)destlen, (const char *)src));
    151                                         } else {
    152                                                 DEBUG(3,("E2BIG: convert_string(%s,%s): srclen=%u destlen=%u\n",
    153                                                          charset_name(ic, from), charset_name(ic, to),
    154                                                         (unsigned int)srclen, (unsigned int)destlen));
    155                                         }
    156                                 }
    157                                 break;
    158                         case EILSEQ:
    159                                 reason="Illegal multibyte sequence";
    160                                 if (!conv_silent)
    161                                         DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",reason,inbuf));
    162                                 if (allow_bad_conv)
    163                                         goto use_as_is;
    164                                
    165                                 return (size_t)-1;
    166                         default:
    167                                 if (!conv_silent)
    168                                         DEBUG(0,("convert_string_internal: Conversion error: %s(%s)\n",reason,inbuf));
    169                                 return (size_t)-1;
    170                 }
    171                 /* smb_panic(reason); */
    172         }
    173         return destlen-o_len;
    174 
    175  use_as_is:
    176 
    177         /*
    178          * Conversion not supported. This is actually an error, but there are so
    179          * many misconfigured iconv systems and smb.conf's out there we can't just
    180          * fail. Do a very bad conversion instead.... JRA.
    181          */
    182 
    183         {
    184                 if (o_len == 0 || i_len == 0)
    185                         return destlen - o_len;
    186 
    187                 if (((from == CH_UTF16LE)||(from == CH_UTF16BE)) &&
    188                                 ((to != CH_UTF16LE)||(to != CH_UTF16BE))) {
    189                         /* Can't convert from utf16 any endian to multibyte.
    190                            Replace with the default fail char.
    191                         */
    192                         if (i_len < 2)
    193                                 return destlen - o_len;
    194                         if (i_len >= 2) {
    195                                 *outbuf = lp_failed_convert_char();
    196 
    197                                 outbuf++;
    198                                 o_len--;
    199 
    200                                 inbuf += 2;
    201                                 i_len -= 2;
    202                         }
    203 
    204                         if (o_len == 0 || i_len == 0)
    205                                 return destlen - o_len;
    206 
    207                         /* Keep trying with the next char... */
    208                         goto again;
    209 
    210                 } else if (from != CH_UTF16LE && from != CH_UTF16BE && to == CH_UTF16LE) {
    211                         /* Can't convert to UTF16LE - just widen by adding the
    212                            default fail char then zero.
    213                         */
    214                         if (o_len < 2)
    215                                 return destlen - o_len;
    216 
    217                         outbuf[0] = lp_failed_convert_char();
    218                         outbuf[1] = '\0';
    219 
    220                         inbuf++;
    221                         i_len--;
    222 
    223                         outbuf += 2;
    224                         o_len -= 2;
    225 
    226                         if (o_len == 0 || i_len == 0)
    227                                 return destlen - o_len;
    228 
    229                         /* Keep trying with the next char... */
    230                         goto again;
    231 
    232                 } else if (from != CH_UTF16LE && from != CH_UTF16BE &&
    233                                 to != CH_UTF16LE && to != CH_UTF16BE) {
    234                         /* Failed multibyte to multibyte. Just copy the default fail char and
    235                                 try again. */
    236                         outbuf[0] = lp_failed_convert_char();
    237 
    238                         inbuf++;
    239                         i_len--;
    240 
    241                         outbuf++;
    242                         o_len--;
    243 
    244                         if (o_len == 0 || i_len == 0)
    245                                 return destlen - o_len;
    246 
    247                         /* Keep trying with the next char... */
    248                         goto again;
    249 
    250                 } else {
    251                         /* Keep compiler happy.... */
    252                         return destlen - o_len;
    253                 }
    254         }
    255 }
    256 
    257 /**
    258  * Convert string from one encoding to another, making error checking etc
    259  * Fast path version - handles ASCII first.
    260  *
    261  * @param src pointer to source string (multibyte or singlebyte)
    262  * @param srclen length of the source string in bytes, or -1 for nul terminated.
    263  * @param dest pointer to destination string (multibyte or singlebyte)
    264  * @param destlen maximal length allowed for string - *NEVER* -1.
    265  * @param allow_bad_conv determines if a "best effort" conversion is acceptable (never returns errors)
    266  * @returns the number of bytes occupied in the destination
    267  *
    268  * Ensure the srclen contains the terminating zero.
    269  *
    270  * This function has been hand-tuned to provide a fast path.
    271  * Don't change unless you really know what you are doing. JRA.
    272  **/
    273 
    274 size_t convert_string(charset_t from, charset_t to,
    275                       void const *src, size_t srclen,
    276                       void *dest, size_t destlen, bool allow_bad_conv)
    277 {
    278         /*
    279          * NB. We deliberately don't do a strlen here if srclen == -1.
    280          * This is very expensive over millions of calls and is taken
    281          * care of in the slow path in convert_string_internal. JRA.
    282          */
    283 
    284 #ifdef DEVELOPER
    285         SMB_ASSERT(destlen != (size_t)-1);
    286 #endif
    287 
    288         if (srclen == 0)
    289                 return 0;
    290 
    291         if (from != CH_UTF16LE && from != CH_UTF16BE && to != CH_UTF16LE && to != CH_UTF16BE) {
    292                 const unsigned char *p = (const unsigned char *)src;
    293                 unsigned char *q = (unsigned char *)dest;
    294                 size_t slen = srclen;
    295                 size_t dlen = destlen;
    296                 unsigned char lastp = '\0';
    297                 size_t retval = 0;
    298 
    299                 /* If all characters are ascii, fast path here. */
    300                 while (slen && dlen) {
    301                         if ((lastp = *p) <= 0x7f) {
    302                                 *q++ = *p++;
    303                                 if (slen != (size_t)-1) {
    304                                         slen--;
    305                                 }
    306                                 dlen--;
    307                                 retval++;
    308                                 if (!lastp)
    309                                         break;
    310                         } else {
    311 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
    312                                 goto general_case;
    313 #else
    314                                 size_t ret = convert_string_internal(from, to, p, slen, q, dlen, allow_bad_conv);
    315                                 if (ret == (size_t)-1) {
    316                                         return ret;
    317                                 }
    318                                 return retval + ret;
    319 #endif
    320                         }
    321                 }
    322                 if (!dlen) {
    323                         /* Even if we fast path we should note if we ran out of room. */
    324                         if (((slen != (size_t)-1) && slen) ||
    325                                         ((slen == (size_t)-1) && lastp)) {
    326                                 errno = E2BIG;
    327                         }
    328                 }
    329                 return retval;
    330         } else if (from == CH_UTF16LE && to != CH_UTF16LE) {
    331                 const unsigned char *p = (const unsigned char *)src;
    332                 unsigned char *q = (unsigned char *)dest;
    333                 size_t retval = 0;
    334                 size_t slen = srclen;
    335                 size_t dlen = destlen;
    336                 unsigned char lastp = '\0';
    337 
    338                 /* If all characters are ascii, fast path here. */
    339                 while (((slen == (size_t)-1) || (slen >= 2)) && dlen) {
    340                         if (((lastp = *p) <= 0x7f) && (p[1] == 0)) {
    341                                 *q++ = *p;
    342                                 if (slen != (size_t)-1) {
    343                                         slen -= 2;
    344                                 }
    345                                 p += 2;
    346                                 dlen--;
    347                                 retval++;
    348                                 if (!lastp)
    349                                         break;
    350                         } else {
    351 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
    352                                 goto general_case;
    353 #else
    354                                 size_t ret = convert_string_internal(from, to, p, slen, q, dlen, allow_bad_conv);
    355                                 if (ret == (size_t)-1) {
    356                                         return ret;
    357                                 }
    358                                 return retval + ret;
    359 #endif
    360                         }
    361                 }
    362                 if (!dlen) {
    363                         /* Even if we fast path we should note if we ran out of room. */
    364                         if (((slen != (size_t)-1) && slen) ||
    365                                         ((slen == (size_t)-1) && lastp)) {
    366                                 errno = E2BIG;
    367                         }
    368                 }
    369                 return retval;
    370         } else if (from != CH_UTF16LE && from != CH_UTF16BE && to == CH_UTF16LE) {
    371                 const unsigned char *p = (const unsigned char *)src;
    372                 unsigned char *q = (unsigned char *)dest;
    373                 size_t retval = 0;
    374                 size_t slen = srclen;
    375                 size_t dlen = destlen;
    376                 unsigned char lastp = '\0';
    377 
    378                 /* If all characters are ascii, fast path here. */
    379                 while (slen && (dlen >= 2)) {
    380                         if ((lastp = *p) <= 0x7F) {
    381                                 *q++ = *p++;
    382                                 *q++ = '\0';
    383                                 if (slen != (size_t)-1) {
    384                                         slen--;
    385                                 }
    386                                 dlen -= 2;
    387                                 retval += 2;
    388                                 if (!lastp)
    389                                         break;
    390                         } else {
    391 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
    392                                 goto general_case;
    393 #else
    394                                 size_t ret = convert_string_internal(from, to, p, slen, q, dlen, allow_bad_conv);
    395                                 if (ret == (size_t)-1) {
    396                                         return ret;
    397                                 }
    398                                 return retval + ret;
    399 #endif
    400                         }
    401                 }
    402                 if (!dlen) {
    403                         /* Even if we fast path we should note if we ran out of room. */
    404                         if (((slen != (size_t)-1) && slen) ||
    405                                         ((slen == (size_t)-1) && lastp)) {
    406                                 errno = E2BIG;
    407                         }
    408                 }
    409                 return retval;
    410         }
    411 
    412 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
    413   general_case:
    414 #endif
    415         return convert_string_internal(from, to, src, srclen, dest, destlen, allow_bad_conv);
    416 }
    417 
    418 /**
    419  * Convert between character sets, allocating a new buffer using talloc for the result.
    420  *
    421  * @param srclen length of source buffer.
    422  * @param dest always set at least to NULL
    423  * @parm converted_size set to the number of bytes occupied by the string in
    424  * the destination on success.
    425  * @note -1 is not accepted for srclen.
    426  *
    427  * @return true if new buffer was correctly allocated, and string was
    428  * converted.
    429  *
    430  * Ensure the srclen contains the terminating zero.
    431  *
    432  * I hate the goto's in this function. It's embarressing.....
    433  * There has to be a cleaner way to do this. JRA.
    434  */
    435 bool convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to,
    436                            void const *src, size_t srclen, void *dst,
    437                            size_t *converted_size, bool allow_bad_conv)
    438 
    439 {
    440         size_t i_len, o_len, destlen = (srclen * 3) / 2;
    441         size_t retval;
    442         const char *inbuf = (const char *)src;
    443         char *outbuf = NULL, *ob = NULL;
    444         smb_iconv_t descriptor;
    445         void **dest = (void **)dst;
    446         struct smb_iconv_convenience *ic;
    447 
    448         *dest = NULL;
    449 
    450         if (!converted_size) {
    451                 errno = EINVAL;
    452                 return false;
    453         }
    454 
    455         if (src == NULL || srclen == (size_t)-1) {
    456                 errno = EINVAL;
    457                 return false;
    458         }
    459 
    460         if (srclen == 0) {
    461                 /* We really should treat this as an error, but
    462                    there are too many callers that need this to
    463                    return a NULL terminated string in the correct
    464                    character set. */
    465                 if (to == CH_UTF16LE|| to == CH_UTF16BE || to == CH_UTF16MUNGED) {
    466                         destlen = 2;
    467                 } else {
    468                         destlen = 1;
    469                 }
    470                 ob = talloc_zero_array(ctx, char, destlen);
    471                 if (ob == NULL) {
    472                         errno = ENOMEM;
    473                         return false;
    474                 }
    475                 *converted_size = destlen;
    476                 *dest = ob;
    477                 return true;
    478         }
    479 
    480         lazy_initialize_conv();
    481         ic = get_iconv_convenience();
    482         descriptor = get_conv_handle(ic, from, to);
    483 
    484         if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
    485                 if (!conv_silent)
    486                         DEBUG(0,("convert_string_talloc: Conversion not supported.\n"));
    487                 errno = EOPNOTSUPP;
    488                 return false;
    489         }
    490 
    491   convert:
    492 
    493         /* +2 is for ucs2 null termination. */
    494         if ((destlen*2)+2 < destlen) {
    495                 /* wrapped ! abort. */
    496                 if (!conv_silent)
    497                         DEBUG(0, ("convert_string_talloc: destlen wrapped !\n"));
    498                 TALLOC_FREE(outbuf);
    499                 errno = EOPNOTSUPP;
    500                 return false;
    501         } else {
    502                 destlen = destlen * 2;
    503         }
    504 
    505         /* +2 is for ucs2 null termination. */
    506         ob = (char *)TALLOC_REALLOC(ctx, ob, destlen + 2);
    507 
    508         if (!ob) {
    509                 DEBUG(0, ("convert_string_talloc: realloc failed!\n"));
    510                 errno = ENOMEM;
    511                 return false;
    512         }
    513         outbuf = ob;
    514         i_len = srclen;
    515         o_len = destlen;
    516 
    517  again:
    518 
    519         retval = smb_iconv(descriptor,
    520                            &inbuf, &i_len,
    521                            &outbuf, &o_len);
    522         if(retval == (size_t)-1)                {
    523                 const char *reason="unknown error";
    524                 switch(errno) {
    525                         case EINVAL:
    526                                 reason="Incomplete multibyte sequence";
    527                                 if (!conv_silent)
    528                                         DEBUG(3,("convert_string_talloc: Conversion error: %s(%s)\n",reason,inbuf));
    529                                 if (allow_bad_conv)
    530                                         goto use_as_is;
    531                                 break;
    532                         case E2BIG:
    533                                 goto convert;
    534                         case EILSEQ:
    535                                 reason="Illegal multibyte sequence";
    536                                 if (!conv_silent)
    537                                         DEBUG(3,("convert_string_talloc: Conversion error: %s(%s)\n",reason,inbuf));
    538                                 if (allow_bad_conv)
    539                                         goto use_as_is;
    540                                 break;
    541                 }
    542                 if (!conv_silent)
    543                         DEBUG(0,("Conversion error: %s(%s)\n",reason,inbuf));
    544                 /* smb_panic(reason); */
    545                 TALLOC_FREE(ob);
    546                 return false;
    547         }
    548 
    549   out:
    550 
    551         destlen = destlen - o_len;
    552         /* Don't shrink unless we're reclaiming a lot of
    553          * space. This is in the hot codepath and these
    554          * reallocs *cost*. JRA.
    555          */
    556         if (o_len > 1024) {
    557                 /* We're shrinking here so we know the +2 is safe from wrap. */
    558                 ob = (char *)TALLOC_REALLOC(ctx,ob,destlen + 2);
    559         }
    560 
    561         if (destlen && !ob) {
    562                 DEBUG(0, ("convert_string_talloc: out of memory!\n"));
    563                 errno = ENOMEM;
    564                 return false;
    565         }
    566 
    567         *dest = ob;
    568 
    569         /* Must ucs2 null terminate in the extra space we allocated. */
    570         ob[destlen] = '\0';
    571         ob[destlen+1] = '\0';
    572 
    573         /* Ensure we can never return a *converted_size of zero. */
    574         if (destlen == 0) {
    575                 /* This can happen from a bad iconv "use_as_is:" call. */
    576                 if (to == CH_UTF16LE|| to == CH_UTF16BE || to == CH_UTF16MUNGED) {
    577                         destlen = 2;
    578                 } else {
    579                         destlen = 1;
    580                 }
    581         }
    582 
    583         *converted_size = destlen;
    584         return true;
    585 
    586  use_as_is:
    587 
    588         /*
    589          * Conversion not supported. This is actually an error, but there are so
    590          * many misconfigured iconv systems and smb.conf's out there we can't just
    591          * fail. Do a very bad conversion instead.... JRA.
    592          */
    593 
    594         {
    595                 if (o_len == 0 || i_len == 0)
    596                         goto out;
    597 
    598                 if (((from == CH_UTF16LE)||(from == CH_UTF16BE)) &&
    599                                 ((to != CH_UTF16LE)||(to != CH_UTF16BE))) {
    600                         /* Can't convert from utf16 any endian to multibyte.
    601                            Replace with the default fail char.
    602                         */
    603 
    604                         if (i_len < 2)
    605                                 goto out;
    606 
    607                         if (i_len >= 2) {
    608                                 *outbuf = lp_failed_convert_char();
    609 
    610                                 outbuf++;
    611                                 o_len--;
    612 
    613                                 inbuf += 2;
    614                                 i_len -= 2;
    615                         }
    616 
    617                         if (o_len == 0 || i_len == 0)
    618                                 goto out;
    619 
    620                         /* Keep trying with the next char... */
    621                         goto again;
    622 
    623                 } else if (from != CH_UTF16LE && from != CH_UTF16BE && to == CH_UTF16LE) {
    624                         /* Can't convert to UTF16LE - just widen by adding the
    625                            default fail char then zero.
    626                         */
    627                         if (o_len < 2)
    628                                 goto out;
    629 
    630                         outbuf[0] = lp_failed_convert_char();
    631                         outbuf[1] = '\0';
    632 
    633                         inbuf++;
    634                         i_len--;
    635 
    636                         outbuf += 2;
    637                         o_len -= 2;
    638 
    639                         if (o_len == 0 || i_len == 0)
    640                                 goto out;
    641 
    642                         /* Keep trying with the next char... */
    643                         goto again;
    644 
    645                 } else if (from != CH_UTF16LE && from != CH_UTF16BE &&
    646                                 to != CH_UTF16LE && to != CH_UTF16BE) {
    647                         /* Failed multibyte to multibyte. Just copy the default fail char and
    648                            try again. */
    649                         outbuf[0] = lp_failed_convert_char();
    650 
    651                         inbuf++;
    652                         i_len--;
    653 
    654                         outbuf++;
    655                         o_len--;
    656 
    657                         if (o_len == 0 || i_len == 0)
    658                                 goto out;
    659 
    660                         /* Keep trying with the next char... */
    661                         goto again;
    662 
    663                 } else {
    664                         /* Keep compiler happy.... */
    665                         goto out;
    666                 }
    667         }
    668 }
    669 
    670 size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
    671 {
    672         size_t size;
    673         smb_ucs2_t *buffer;
    674 
    675         if (!push_ucs2_talloc(talloc_tos(), &buffer, src, &size)) {
    676                 return (size_t)-1;
    677         }
    678 
    679         if (!strupper_w(buffer) && (dest == src)) {
    680                 TALLOC_FREE(buffer);
    681                 return srclen;
    682         }
    683 
    684         size = convert_string(CH_UTF16LE, CH_UNIX, buffer, size, dest, destlen, True);
    685         TALLOC_FREE(buffer);
    686         return size;
    687 }
    688 
    689 /**
    690  talloc_strdup() a unix string to upper case.
    691 **/
    692 
    693 char *talloc_strdup_upper(TALLOC_CTX *ctx, const char *s)
    694 {
    695         char *out_buffer = talloc_strdup(ctx,s);
    696         const unsigned char *p = (const unsigned char *)s;
    697         unsigned char *q = (unsigned char *)out_buffer;
    698 
    699         if (!q) {
    700                 return NULL;
    701         }
    702 
    703         /* this is quite a common operation, so we want it to be
    704            fast. We optimise for the ascii case, knowing that all our
    705            supported multi-byte character sets are ascii-compatible
    706            (ie. they match for the first 128 chars) */
    707 
    708         while (*p) {
    709                 if (*p & 0x80)
    710                         break;
    711                 *q++ = toupper_ascii_fast(*p);
    712                 p++;
    713         }
    714 
    715         if (*p) {
    716                 /* MB case. */
    717                 size_t converted_size, converted_size2;
    718                 smb_ucs2_t *ubuf = NULL;
    719 
    720                 /* We're not using the ascii buffer above. */
    721                 TALLOC_FREE(out_buffer);
    722 
    723                 if (!convert_string_talloc(ctx, CH_UNIX, CH_UTF16LE, s,
    724                                            strlen(s)+1, (void *)&ubuf,
    725                                            &converted_size, True))
    726                 {
    727                         return NULL;
    728                 }
    729 
    730                 strupper_w(ubuf);
    731 
    732                 if (!convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, ubuf,
    733                                            converted_size, (void *)&out_buffer,
    734                                            &converted_size2, True))
    735                 {
    736                         TALLOC_FREE(ubuf);
    737                         return NULL;
    738                 }
    739 
    740                 /* Don't need the intermediate buffer
    741                  * anymore.
    742                  */
    743                 TALLOC_FREE(ubuf);
    744         }
    745 
    746         return out_buffer;
    747 }
    748 
    749 char *strupper_talloc(TALLOC_CTX *ctx, const char *s) {
    750         return talloc_strdup_upper(ctx, s);
    751 }
    752 
    753 
    754 size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
    755 {
    756         size_t size;
    757         smb_ucs2_t *buffer = NULL;
    758 
    759         if (!convert_string_talloc(talloc_tos(), CH_UNIX, CH_UTF16LE, src, srclen,
    760                                    (void **)(void *)&buffer, &size,
    761                                    True))
    762         {
    763                 smb_panic("failed to create UCS2 buffer");
    764         }
    765         if (!strlower_w(buffer) && (dest == src)) {
    766                 TALLOC_FREE(buffer);
    767                 return srclen;
    768         }
    769         size = convert_string(CH_UTF16LE, CH_UNIX, buffer, size, dest, destlen, True);
    770         TALLOC_FREE(buffer);
    771         return size;
    772 }
    773 
    774 
    775 char *talloc_strdup_lower(TALLOC_CTX *ctx, const char *s)
    776 {
    777         size_t converted_size;
    778         smb_ucs2_t *buffer = NULL;
    779         char *out_buffer;
    780 
    781         if (!push_ucs2_talloc(ctx, &buffer, s, &converted_size)) {
    782                 return NULL;
    783         }
    784 
    785         strlower_w(buffer);
    786 
    787         if (!pull_ucs2_talloc(ctx, &out_buffer, buffer, &converted_size)) {
    788                 TALLOC_FREE(buffer);
    789                 return NULL;
    790         }
    791 
    792         TALLOC_FREE(buffer);
    793 
    794         return out_buffer;
    795 }
    796 
    797 char *strlower_talloc(TALLOC_CTX *ctx, const char *s) {
    798         return talloc_strdup_lower(ctx, s);
    799 }
    800 
    801 size_t ucs2_align(const void *base_ptr, const void *p, int flags)
    802 {
    803         if (flags & (STR_NOALIGN|STR_ASCII))
    804                 return 0;
    805         return PTR_DIFF(p, base_ptr) & 1;
    806 }
    807 
     30        TALLOC_FREE(global_iconv_handle);
     31}
    80832
    80933/**
     
    82549        size_t src_len = 0;
    82650        char *tmpbuf = NULL;
    827         size_t ret;
     51        size_t size = 0;
     52        bool ret;
    82853
    82954        /* No longer allow a length of -1. */
     
    83762                        smb_panic("malloc fail");
    83863                }
    839                 strupper_m(tmpbuf);
     64                if (!strupper_m(tmpbuf)) {
     65                        if ((flags & (STR_TERMINATE|STR_TERMINATE_ASCII)) &&
     66                                        dest &&
     67                                        dest_len > 0) {
     68                                *(char *)dest = 0;
     69                        }
     70                        SAFE_FREE(tmpbuf);
     71                        return 0;
     72                }
    84073                src = tmpbuf;
    84174        }
     
    84679        }
    84780
    848         ret = convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len, True);
    849 
     81        ret = convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len, &size);
    85082        SAFE_FREE(tmpbuf);
    851         if (ret == (size_t)-1) {
    852                 if ((flags & (STR_TERMINATE | STR_TERMINATE_ASCII))
    853                                 && dest_len > 0) {
     83        if (ret == false) {
     84                if ((flags & (STR_TERMINATE | STR_TERMINATE_ASCII)) &&
     85                                dest_len > 0) {
    85486                        ((char *)dest)[0] = '\0';
    85587                }
    85688                return 0;
    85789        }
    858         return ret;
    859 }
    860 
    861 size_t push_ascii_fstring(void *dest, const char *src)
    862 {
    863         return push_ascii(dest, src, sizeof(fstring), STR_TERMINATE);
    864 }
    865 
    866 /********************************************************************
    867  Push an nstring - ensure null terminated. Written by
    868  moriyama@miraclelinux.com (MORIYAMA Masayuki).
    869 ********************************************************************/
    870 
    871 size_t push_ascii_nstring(void *dest, const char *src)
    872 {
    873         size_t i, buffer_len, dest_len;
    874         smb_ucs2_t *buffer;
    875 
    876         conv_silent = True;
    877         if (!push_ucs2_talloc(talloc_tos(), &buffer, src, &buffer_len)) {
    878                 smb_panic("failed to create UCS2 buffer");
    879         }
    880 
    881         /* We're using buffer_len below to count ucs2 characters, not bytes. */
    882         buffer_len /= sizeof(smb_ucs2_t);
    883 
    884         dest_len = 0;
    885         for (i = 0; buffer[i] != 0 && (i < buffer_len); i++) {
    886                 unsigned char mb[10];
    887                 /* Convert one smb_ucs2_t character at a time. */
    888                 size_t mb_len = convert_string(CH_UTF16LE, CH_DOS, buffer+i, sizeof(smb_ucs2_t), mb, sizeof(mb), False);
    889                 if ((mb_len != (size_t)-1) && (dest_len + mb_len <= MAX_NETBIOSNAME_LEN - 1)) {
    890                         memcpy((char *)dest + dest_len, mb, mb_len);
    891                         dest_len += mb_len;
    892                 } else {
    893                         errno = E2BIG;
    894                         break;
    895                 }
    896         }
    897         ((char *)dest)[dest_len] = '\0';
    898 
    899         conv_silent = False;
    900         TALLOC_FREE(buffer);
    901         return dest_len;
     90        return size;
    90291}
    90392
     
    90594 Push and malloc an ascii string. src and dest null terminated.
    90695********************************************************************/
    907 
    908 bool push_ascii_talloc(TALLOC_CTX *mem_ctx, char **dest, const char *src, size_t *converted_size)
    909 {
    910         size_t src_len = strlen(src)+1;
    911 
    912         *dest = NULL;
    913         return convert_string_talloc(mem_ctx, CH_UNIX, CH_DOS, src, src_len,
    914                                      (void **)dest, converted_size, True);
    915 }
    91696
    91797/**
     
    932112size_t pull_ascii(char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
    933113{
    934         size_t ret;
     114        bool ret;
     115        size_t size = 0;
    935116
    936117        if (dest_len == (size_t)-1) {
     
    950131        }
    951132
    952         ret = convert_string(CH_DOS, CH_UNIX, src, src_len, dest, dest_len, True);
    953         if (ret == (size_t)-1) {
    954                 ret = 0;
     133        ret = convert_string(CH_DOS, CH_UNIX, src, src_len, dest, dest_len, &size);
     134        if (ret == false) {
     135                size = 0;
    955136                dest_len = 0;
    956137        }
    957138
    958         if (dest_len && ret) {
     139        if (dest_len && size) {
    959140                /* Did we already process the terminating zero ? */
    960                 if (dest[MIN(ret-1, dest_len-1)] != 0) {
    961                         dest[MIN(ret, dest_len-1)] = 0;
     141                if (dest[MIN(size-1, dest_len-1)] != 0) {
     142                        dest[MIN(size, dest_len-1)] = 0;
    962143                }
    963144        } else  {
     
    1000181        }
    1001182
     183        if (src_len == (size_t)-1) {
     184                smb_panic("src_len == -1 in pull_ascii_base_talloc");
     185        }
     186
    1002187        if (flags & STR_TERMINATE) {
    1003                 if (src_len == (size_t)-1) {
    1004                         src_len = strlen((const char *)src) + 1;
    1005                 } else {
    1006                         size_t len = strnlen((const char *)src, src_len);
    1007                         if (len < src_len)
    1008                                 len++;
    1009                         src_len = len;
    1010                 }
     188                size_t len = strnlen((const char *)src, src_len);
     189                if (len < src_len)
     190                        len++;
     191                src_len = len;
    1011192                /* Ensure we don't use an insane length from the client. */
    1012193                if (src_len >= 1024*1024) {
     
    1017198                        smb_panic(msg);
    1018199                }
    1019         } else {
    1020                 /* Can't have an unlimited length
    1021                  * non STR_TERMINATE'd.
    1022                  */
    1023                 if (src_len == (size_t)-1) {
    1024                         errno = EINVAL;
    1025                         return 0;
    1026                 }
    1027200        }
    1028201
     
    1030203
    1031204        if (!convert_string_talloc(ctx, CH_DOS, CH_UNIX, src, src_len, &dest,
    1032                                      &dest_len, True)) {
     205                                     &dest_len)) {
    1033206                dest_len = 0;
    1034207        }
     
    1041214                        if (size <= dest_len) {
    1042215                                /* No, realloc. */
    1043                                 dest = TALLOC_REALLOC_ARRAY(ctx, dest, char,
     216                                dest = talloc_realloc(ctx, dest, char,
    1044217                                                dest_len+1);
    1045218                                if (!dest) {
     
    1061234}
    1062235
    1063 size_t pull_ascii_fstring(char *dest, const void *src)
    1064 {
    1065         return pull_ascii(dest, src, sizeof(fstring), -1, STR_TERMINATE);
    1066 }
    1067 
    1068 /* When pulling an nstring it can expand into a larger size (dos cp -> utf8). Cope with this. */
    1069 
    1070 size_t pull_ascii_nstring(char *dest, size_t dest_len, const void *src)
    1071 {
    1072         return pull_ascii(dest, src, dest_len, sizeof(nstring)-1, STR_TERMINATE);
    1073 }
    1074 
    1075236/**
    1076237 * Copy a string from a char* src to a unicode destination.
     
    1090251 **/
    1091252
    1092 size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_len, int flags)
     253static size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_len, int flags)
    1093254{
    1094255        size_t len=0;
    1095256        size_t src_len;
    1096         size_t ret;
     257        size_t size = 0;
     258        bool ret;
    1097259
    1098260        if (dest_len == (size_t)-1) {
     
    1117279        dest_len &= ~1;
    1118280
    1119         ret =  convert_string(CH_UNIX, CH_UTF16LE, src, src_len, dest, dest_len, True);
    1120         if (ret == (size_t)-1) {
     281        ret = convert_string(CH_UNIX, CH_UTF16LE, src, src_len, dest, dest_len, &size);
     282        if (ret == false) {
    1121283                if ((flags & STR_TERMINATE) &&
    1122284                                dest &&
     
    1127289        }
    1128290
    1129         len += ret;
     291        len += size;
    1130292
    1131293        if (flags & STR_UPPER) {
     
    1133295                size_t i;
    1134296
    1135                 /* We check for i < (ret / 2) below as the dest string isn't null
     297                /* We check for i < (size / 2) below as the dest string isn't null
    1136298                   terminated if STR_TERMINATE isn't set. */
    1137299
    1138                 for (i = 0; i < (ret / 2) && i < (dest_len / 2) && dest_ucs2[i]; i++) {
     300                for (i = 0; i < (size / 2) && i < (dest_len / 2) && dest_ucs2[i]; i++) {
    1139301                        smb_ucs2_t v = toupper_w(dest_ucs2[i]);
    1140302                        if (v != dest_ucs2[i]) {
     
    1145307
    1146308        return len;
    1147 }
    1148 
    1149 
    1150 /**
    1151  * Copy a string from a unix char* src to a UCS2 destination,
    1152  * allocating a buffer using talloc().
    1153  *
    1154  * @param dest always set at least to NULL
    1155  * @parm converted_size set to the number of bytes occupied by the string in
    1156  * the destination on success.
    1157  *
    1158  * @return true if new buffer was correctly allocated, and string was
    1159  * converted.
    1160  **/
    1161 bool push_ucs2_talloc(TALLOC_CTX *ctx, smb_ucs2_t **dest, const char *src,
    1162                       size_t *converted_size)
    1163 {
    1164         size_t src_len = strlen(src)+1;
    1165 
    1166         *dest = NULL;
    1167         return convert_string_talloc(ctx, CH_UNIX, CH_UTF16LE, src, src_len,
    1168                                      (void **)dest, converted_size, True);
    1169 }
    1170 
    1171 
    1172 /**
    1173  Copy a string from a char* src to a UTF-8 destination.
    1174  Return the number of bytes occupied by the string in the destination
    1175  Flags can have:
    1176   STR_TERMINATE means include the null termination
    1177   STR_UPPER     means uppercase in the destination
    1178  dest_len is the maximum length allowed in the destination. If dest_len
    1179  is -1 then no maxiumum is used.
    1180 **/
    1181 
    1182 static size_t push_utf8(void *dest, const char *src, size_t dest_len, int flags)
    1183 {
    1184         size_t src_len = 0;
    1185         size_t ret;
    1186         char *tmpbuf = NULL;
    1187 
    1188         if (dest_len == (size_t)-1) {
    1189                 /* No longer allow dest_len of -1. */
    1190                 smb_panic("push_utf8 - invalid dest_len of -1");
    1191         }
    1192 
    1193         if (flags & STR_UPPER) {
    1194                 tmpbuf = strupper_talloc(talloc_tos(), src);
    1195                 if (!tmpbuf) {
    1196                         return (size_t)-1;
    1197                 }
    1198                 src = tmpbuf;
    1199                 src_len = strlen(src);
    1200         }
    1201 
    1202         src_len = strlen(src);
    1203         if (flags & STR_TERMINATE) {
    1204                 src_len++;
    1205         }
    1206 
    1207         ret = convert_string(CH_UNIX, CH_UTF8, src, src_len, dest, dest_len, True);
    1208         TALLOC_FREE(tmpbuf);
    1209         return ret;
    1210 }
    1211 
    1212 size_t push_utf8_fstring(void *dest, const char *src)
    1213 {
    1214         return push_utf8(dest, src, sizeof(fstring), STR_TERMINATE);
    1215 }
    1216 
    1217 /**
    1218  * Copy a string from a unix char* src to a UTF-8 destination, allocating a buffer using talloc
    1219  *
    1220  * @param dest always set at least to NULL
    1221  * @parm converted_size set to the number of bytes occupied by the string in
    1222  * the destination on success.
    1223  *
    1224  * @return true if new buffer was correctly allocated, and string was
    1225  * converted.
    1226  **/
    1227 
    1228 bool push_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src,
    1229                       size_t *converted_size)
    1230 {
    1231         size_t src_len = strlen(src)+1;
    1232 
    1233         *dest = NULL;
    1234         return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len,
    1235                                      (void**)dest, converted_size, True);
    1236 }
    1237 
    1238 /**
    1239  Copy a string from a ucs2 source to a unix char* destination.
    1240  Flags can have:
    1241   STR_TERMINATE means the string in src is null terminated.
    1242   STR_NOALIGN   means don't try to align.
    1243  if STR_TERMINATE is set then src_len is ignored if it is -1.
    1244  src_len is the length of the source area in bytes
    1245  Return the number of bytes occupied by the string in src.
    1246  The resulting string in "dest" is always null terminated.
    1247 **/
    1248 
    1249 size_t pull_ucs2(const void *base_ptr, char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
    1250 {
    1251         size_t ret;
    1252         size_t ucs2_align_len = 0;
    1253 
    1254         if (dest_len == (size_t)-1) {
    1255                 /* No longer allow dest_len of -1. */
    1256                 smb_panic("pull_ucs2 - invalid dest_len of -1");
    1257         }
    1258 
    1259         if (!src_len) {
    1260                 if (dest && dest_len > 0) {
    1261                         dest[0] = '\0';
    1262                 }
    1263                 return 0;
    1264         }
    1265 
    1266         if (ucs2_align(base_ptr, src, flags)) {
    1267                 src = (const void *)((const char *)src + 1);
    1268                 if (src_len != (size_t)-1)
    1269                         src_len--;
    1270                 ucs2_align_len = 1;
    1271         }
    1272 
    1273         if (flags & STR_TERMINATE) {
    1274                 /* src_len -1 is the default for null terminated strings. */
    1275                 if (src_len != (size_t)-1) {
    1276                         size_t len = strnlen_w((const smb_ucs2_t *)src,
    1277                                                 src_len/2);
    1278                         if (len < src_len/2)
    1279                                 len++;
    1280                         src_len = len*2;
    1281                 }
    1282         }
    1283 
    1284         /* ucs2 is always a multiple of 2 bytes */
    1285         if (src_len != (size_t)-1)
    1286                 src_len &= ~1;
    1287 
    1288         ret = convert_string(CH_UTF16LE, CH_UNIX, src, src_len, dest, dest_len, True);
    1289         if (ret == (size_t)-1) {
    1290                 ret = 0;
    1291                 dest_len = 0;
    1292         }
    1293 
    1294         if (src_len == (size_t)-1)
    1295                 src_len = ret*2;
    1296 
    1297         if (dest_len && ret) {
    1298                 /* Did we already process the terminating zero ? */
    1299                 if (dest[MIN(ret-1, dest_len-1)] != 0) {
    1300                         dest[MIN(ret, dest_len-1)] = 0;
    1301                 }
    1302         } else {
    1303                 dest[0] = 0;
    1304         }
    1305 
    1306         return src_len + ucs2_align_len;
    1307309}
    1308310
     
    1321323**/
    1322324
    1323 size_t pull_ucs2_base_talloc(TALLOC_CTX *ctx,
    1324                         const void *base_ptr,
    1325                         char **ppdest,
    1326                         const void *src,
    1327                         size_t src_len,
    1328                         int flags)
     325static size_t pull_ucs2_base_talloc(TALLOC_CTX *ctx,
     326                                    const void *base_ptr,
     327                                    char **ppdest,
     328                                    const void *src,
     329                                    size_t src_len,
     330                                    int flags)
    1329331{
    1330332        char *dest;
     
    1345347        }
    1346348
     349        if (src_len == (size_t)-1) {
     350                /* no longer used anywhere, but worth checking */
     351                smb_panic("sec_len == -1 in pull_ucs2_base_talloc");
     352        }
     353
    1347354        if (ucs2_align(base_ptr, src, flags)) {
    1348355                src = (const void *)((const char *)src + 1);
    1349                 if (src_len != (size_t)-1)
    1350                         src_len--;
     356                src_len--;
    1351357                ucs2_align_len = 1;
    1352358        }
     
    1354360        if (flags & STR_TERMINATE) {
    1355361                /* src_len -1 is the default for null terminated strings. */
    1356                 if (src_len != (size_t)-1) {
    1357                         size_t len = strnlen_w((const smb_ucs2_t *)src,
    1358                                                 src_len/2);
    1359                         if (len < src_len/2)
    1360                                 len++;
    1361                         src_len = len*2;
    1362                 } else {
    1363                         /*
    1364                          * src_len == -1 - alloc interface won't take this
    1365                          * so we must calculate.
    1366                          */
    1367                         src_len = (strlen_w((const smb_ucs2_t *)src)+1)*sizeof(smb_ucs2_t);
    1368                 }
     362                size_t len = strnlen_w((const smb_ucs2_t *)src,
     363                                       src_len/2);
     364                if (len < src_len/2)
     365                        len++;
     366                src_len = len*2;
     367
    1369368                /* Ensure we don't use an insane length from the client. */
    1370369                if (src_len >= 1024*1024) {
    1371370                        smb_panic("Bad src length in pull_ucs2_base_talloc\n");
    1372371                }
    1373         } else {
    1374                 /* Can't have an unlimited length
    1375                  * non STR_TERMINATE'd.
    1376                  */
    1377                 if (src_len == (size_t)-1) {
    1378                         errno = EINVAL;
    1379                         return 0;
    1380                 }
    1381         }
    1382 
    1383         /* src_len != -1 here. */
     372        }
    1384373
    1385374        /* ucs2 is always a multiple of 2 bytes */
     
    1387376
    1388377        if (!convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, src, src_len,
    1389                                    (void *)&dest, &dest_len, True)) {
     378                                   (void *)&dest, &dest_len)) {
    1390379                dest_len = 0;
    1391380        }
     
    1398387                        if (size <= dest_len) {
    1399388                                /* No, realloc. */
    1400                                 dest = TALLOC_REALLOC_ARRAY(ctx, dest, char,
     389                                dest = talloc_realloc(ctx, dest, char,
    1401390                                                dest_len+1);
    1402391                                if (!dest) {
     
    1416405        *ppdest = dest;
    1417406        return src_len + ucs2_align_len;
    1418 }
    1419 
    1420 size_t pull_ucs2_fstring(char *dest, const void *src)
    1421 {
    1422         return pull_ucs2(NULL, dest, src, sizeof(fstring), -1, STR_TERMINATE);
    1423 }
    1424 
    1425 /**
    1426  * Copy a string from a UCS2 src to a unix char * destination, allocating a buffer using talloc
    1427  *
    1428  * @param dest always set at least to NULL
    1429  * @parm converted_size set to the number of bytes occupied by the string in
    1430  * the destination on success.
    1431  *
    1432  * @return true if new buffer was correctly allocated, and string was
    1433  * converted.
    1434  **/
    1435 
    1436 bool pull_ucs2_talloc(TALLOC_CTX *ctx, char **dest, const smb_ucs2_t *src,
    1437                       size_t *converted_size)
    1438 {
    1439         size_t src_len = (strlen_w(src)+1) * sizeof(smb_ucs2_t);
    1440 
    1441         *dest = NULL;
    1442         return convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, src, src_len,
    1443                                      (void **)dest, converted_size, True);
    1444 }
    1445 
    1446 /**
    1447  * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer using talloc
    1448  *
    1449  * @param dest always set at least to NULL
    1450  * @parm converted_size set to the number of bytes occupied by the string in
    1451  * the destination on success.
    1452  *
    1453  * @return true if new buffer was correctly allocated, and string was
    1454  * converted.
    1455  **/
    1456 
    1457 bool pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src,
    1458                       size_t *converted_size)
    1459 {
    1460         size_t src_len = strlen(src)+1;
    1461 
    1462         *dest = NULL;
    1463         return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len,
    1464                                      (void **)dest, converted_size, True);
    1465 }
    1466 
    1467  
    1468 /**
    1469  * Copy a string from a DOS src to a unix char * destination, allocating a buffer using talloc
    1470  *
    1471  * @param dest always set at least to NULL
    1472  * @parm converted_size set to the number of bytes occupied by the string in
    1473  * the destination on success.
    1474  *
    1475  * @return true if new buffer was correctly allocated, and string was
    1476  * converted.
    1477  **/
    1478 
    1479 bool pull_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src,
    1480                        size_t *converted_size)
    1481 {
    1482         size_t src_len = strlen(src)+1;
    1483 
    1484         *dest = NULL;
    1485         return convert_string_talloc(ctx, CH_DOS, CH_UNIX, src, src_len,
    1486                                      (void **)dest, converted_size, True);
    1487407}
    1488408
     
    1501421**/
    1502422
    1503 size_t push_string_check_fn(const char *function, unsigned int line,
    1504                             void *dest, const char *src,
    1505                             size_t dest_len, int flags)
    1506 {
    1507 #ifdef DEVELOPER
    1508         /* We really need to zero fill here, not clobber
    1509          * region, as we want to ensure that valgrind thinks
    1510          * all of the outgoing buffer has been written to
    1511          * so a send() or write() won't trap an error.
    1512          * JRA.
    1513          */
    1514 #if 0
    1515         clobber_region(function, line, dest, dest_len);
    1516 #else
    1517         memset(dest, '\0', dest_len);
    1518 #endif
    1519 #endif
    1520 
     423size_t push_string_check_fn(void *dest, const char *src,
     424                         size_t dest_len, int flags)
     425{
    1521426        if (!(flags & STR_ASCII) && (flags & STR_UNICODE)) {
    1522427                return push_ucs2(NULL, dest, src, dest_len, flags);
     
    1540445**/
    1541446
    1542 size_t push_string_base(const char *function, unsigned int line,
    1543                         const char *base, uint16 flags2,
     447size_t push_string_base(const char *base, uint16_t flags2,
    1544448                        void *dest, const char *src,
    1545449                        size_t dest_len, int flags)
    1546450{
    1547 #ifdef DEVELOPER
    1548         /* We really need to zero fill here, not clobber
    1549          * region, as we want to ensure that valgrind thinks
    1550          * all of the outgoing buffer has been written to
    1551          * so a send() or write() won't trap an error.
    1552          * JRA.
    1553          */
    1554 #if 0
    1555         clobber_region(function, line, dest, dest_len);
    1556 #else
    1557         memset(dest, '\0', dest_len);
    1558 #endif
    1559 #endif
    1560451
    1561452        if (!(flags & STR_ASCII) && \
     
    1565456        }
    1566457        return push_ascii(dest, src, dest_len, flags);
    1567 }
    1568 
    1569 /**
    1570  Copy a string from a char* src to a unicode or ascii
    1571  dos codepage destination choosing unicode or ascii based on the
    1572  flags supplied
    1573  Return the number of bytes occupied by the string in the destination.
    1574  flags can have:
    1575   STR_TERMINATE means include the null termination.
    1576   STR_UPPER     means uppercase in the destination.
    1577   STR_ASCII     use ascii even with unicode packet.
    1578   STR_NOALIGN   means don't do alignment.
    1579  dest_len is the maximum length allowed in the destination. If dest_len
    1580  is -1 then no maxiumum is used.
    1581 **/
    1582 
    1583 ssize_t push_string(void *dest, const char *src, size_t dest_len, int flags)
    1584 {
    1585         size_t ret;
    1586 #ifdef DEVELOPER
    1587         /* We really need to zero fill here, not clobber
    1588          * region, as we want to ensure that valgrind thinks
    1589          * all of the outgoing buffer has been written to
    1590          * so a send() or write() won't trap an error.
    1591          * JRA.
    1592          */
    1593         memset(dest, '\0', dest_len);
    1594 #endif
    1595 
    1596         if (!(flags & STR_ASCII) && \
    1597             (flags & STR_UNICODE)) {
    1598                 ret = push_ucs2(NULL, dest, src, dest_len, flags);
    1599         } else {
    1600                 ret = push_ascii(dest, src, dest_len, flags);
    1601         }
    1602         if (ret == (size_t)-1) {
    1603                 return -1;
    1604         }
    1605         return ret;
    1606 }
    1607 
    1608 /**
    1609  Copy a string from a unicode or ascii source (depending on
    1610  the packet flags) to a char* destination.
    1611  Flags can have:
    1612   STR_TERMINATE means the string in src is null terminated.
    1613   STR_UNICODE   means to force as unicode.
    1614   STR_ASCII     use ascii even with unicode packet.
    1615   STR_NOALIGN   means don't do alignment.
    1616  if STR_TERMINATE is set then src_len is ignored is it is -1
    1617  src_len is the length of the source area in bytes.
    1618  Return the number of bytes occupied by the string in src.
    1619  The resulting string in "dest" is always null terminated.
    1620 **/
    1621 
    1622 size_t pull_string_fn(const char *function,
    1623                         unsigned int line,
    1624                         const void *base_ptr,
    1625                         uint16 smb_flags2,
    1626                         char *dest,
    1627                         const void *src,
    1628                         size_t dest_len,
    1629                         size_t src_len,
    1630                         int flags)
    1631 {
    1632 #ifdef DEVELOPER
    1633         clobber_region(function, line, dest, dest_len);
    1634 #endif
    1635 
    1636         if ((base_ptr == NULL) && ((flags & (STR_ASCII|STR_UNICODE)) == 0)) {
    1637                 smb_panic("No base ptr to get flg2 and neither ASCII nor "
    1638                           "UNICODE defined");
    1639         }
    1640 
    1641         if (!(flags & STR_ASCII) && \
    1642             ((flags & STR_UNICODE || \
    1643               (smb_flags2 & FLAGS2_UNICODE_STRINGS)))) {
    1644                 return pull_ucs2(base_ptr, dest, src, dest_len, src_len, flags);
    1645         }
    1646         return pull_ascii(dest, src, dest_len, src_len, flags);
    1647458}
    1648459
     
    1662473**/
    1663474
    1664 size_t pull_string_talloc_fn(const char *function,
    1665                         unsigned int line,
    1666                         TALLOC_CTX *ctx,
    1667                         const void *base_ptr,
    1668                         uint16 smb_flags2,
    1669                         char **ppdest,
    1670                         const void *src,
    1671                         size_t src_len,
    1672                         int flags)
     475size_t pull_string_talloc(TALLOC_CTX *ctx,
     476                          const void *base_ptr,
     477                          uint16_t smb_flags2,
     478                          char **ppdest,
     479                          const void *src,
     480                          size_t src_len,
     481                          int flags)
    1673482{
    1674483        if ((base_ptr == NULL) && ((flags & (STR_ASCII|STR_UNICODE)) == 0)) {
     
    1694503}
    1695504
    1696 
    1697 size_t align_string(const void *base_ptr, const char *p, int flags)
    1698 {
    1699         if (!(flags & STR_ASCII) && \
    1700             ((flags & STR_UNICODE || \
    1701               (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) {
    1702                 return ucs2_align(base_ptr, p, flags);
    1703         }
    1704         return 0;
    1705 }
    1706 
     505/*******************************************************************
     506 Write a string in (little-endian) unicode format. src is in
     507 the current DOS codepage. len is the length in bytes of the
     508 string pointed to by dst.
     509
     510 if null_terminate is True then null terminate the packet (adds 2 bytes)
     511
     512 the return value is the length in bytes consumed by the string, including the
     513 null termination if applied
     514********************************************************************/
     515
     516size_t dos_PutUniCode(char *dst,const char *src, size_t len, bool null_terminate)
     517{
     518        int flags = null_terminate ? STR_UNICODE|STR_NOALIGN|STR_TERMINATE
     519                                   : STR_UNICODE|STR_NOALIGN;
     520        return push_ucs2(NULL, dst, src, len, flags);
     521}
     522
     523
     524/* Converts a string from internal samba format to unicode. Always terminates.
     525 * Actually just a wrapper round push_ucs2_talloc().
     526 */
     527
     528int rpcstr_push_talloc(TALLOC_CTX *ctx, smb_ucs2_t **dest, const char *src)
     529{
     530        size_t size;
     531        if (push_ucs2_talloc(ctx, dest, src, &size))
     532                return size;
     533        else
     534                return -1;
     535}
Note: See TracChangeset for help on using the changeset viewer.