Changeset 988 for vendor/current/source3/lib/charcnv.c
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/lib/charcnv.c
r871 r988 23 23 #include "includes.h" 24 24 25 /* We can parameterize this if someone complains.... JRA. */26 27 char lp_failed_convert_char(void)28 {29 return '_';30 }31 32 /**33 * @file34 *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 is39 * <b>not</b> necessarily UTF-8 and may be different on machines that40 * need i18n filenames to be compatible with Unix software. It does41 * have to be a superset of ASCII. All multibyte sequences must start42 * with a byte with the high bit set.43 *44 * @sa lib/iconv.c45 */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 60 25 /** 61 26 * Destroy global objects allocated by init_iconv() … … 63 28 void gfree_charcnv(void) 64 29 { 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 } 808 32 809 33 /** … … 825 49 size_t src_len = 0; 826 50 char *tmpbuf = NULL; 827 size_t ret; 51 size_t size = 0; 52 bool ret; 828 53 829 54 /* No longer allow a length of -1. */ … … 837 62 smb_panic("malloc fail"); 838 63 } 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 } 840 73 src = tmpbuf; 841 74 } … … 846 79 } 847 80 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); 850 82 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) { 854 86 ((char *)dest)[0] = '\0'; 855 87 } 856 88 return 0; 857 89 } 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; 902 91 } 903 92 … … 905 94 Push and malloc an ascii string. src and dest null terminated. 906 95 ********************************************************************/ 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 }916 96 917 97 /** … … 932 112 size_t pull_ascii(char *dest, const void *src, size_t dest_len, size_t src_len, int flags) 933 113 { 934 size_t ret; 114 bool ret; 115 size_t size = 0; 935 116 936 117 if (dest_len == (size_t)-1) { … … 950 131 } 951 132 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; 955 136 dest_len = 0; 956 137 } 957 138 958 if (dest_len && ret) {139 if (dest_len && size) { 959 140 /* 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; 962 143 } 963 144 } else { … … 1000 181 } 1001 182 183 if (src_len == (size_t)-1) { 184 smb_panic("src_len == -1 in pull_ascii_base_talloc"); 185 } 186 1002 187 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; 1011 192 /* Ensure we don't use an insane length from the client. */ 1012 193 if (src_len >= 1024*1024) { … … 1017 198 smb_panic(msg); 1018 199 } 1019 } else {1020 /* Can't have an unlimited length1021 * non STR_TERMINATE'd.1022 */1023 if (src_len == (size_t)-1) {1024 errno = EINVAL;1025 return 0;1026 }1027 200 } 1028 201 … … 1030 203 1031 204 if (!convert_string_talloc(ctx, CH_DOS, CH_UNIX, src, src_len, &dest, 1032 &dest_len , True)) {205 &dest_len)) { 1033 206 dest_len = 0; 1034 207 } … … 1041 214 if (size <= dest_len) { 1042 215 /* No, realloc. */ 1043 dest = TALLOC_REALLOC_ARRAY(ctx, dest, char,216 dest = talloc_realloc(ctx, dest, char, 1044 217 dest_len+1); 1045 218 if (!dest) { … … 1061 234 } 1062 235 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 1075 236 /** 1076 237 * Copy a string from a char* src to a unicode destination. … … 1090 251 **/ 1091 252 1092 s ize_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_len, int flags)253 static size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_len, int flags) 1093 254 { 1094 255 size_t len=0; 1095 256 size_t src_len; 1096 size_t ret; 257 size_t size = 0; 258 bool ret; 1097 259 1098 260 if (dest_len == (size_t)-1) { … … 1117 279 dest_len &= ~1; 1118 280 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) { 1121 283 if ((flags & STR_TERMINATE) && 1122 284 dest && … … 1127 289 } 1128 290 1129 len += ret;291 len += size; 1130 292 1131 293 if (flags & STR_UPPER) { … … 1133 295 size_t i; 1134 296 1135 /* We check for i < ( ret/ 2) below as the dest string isn't null297 /* We check for i < (size / 2) below as the dest string isn't null 1136 298 terminated if STR_TERMINATE isn't set. */ 1137 299 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++) { 1139 301 smb_ucs2_t v = toupper_w(dest_ucs2[i]); 1140 302 if (v != dest_ucs2[i]) { … … 1145 307 1146 308 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 NULL1155 * @parm converted_size set to the number of bytes occupied by the string in1156 * the destination on success.1157 *1158 * @return true if new buffer was correctly allocated, and string was1159 * 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 destination1175 Flags can have:1176 STR_TERMINATE means include the null termination1177 STR_UPPER means uppercase in the destination1178 dest_len is the maximum length allowed in the destination. If dest_len1179 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 talloc1219 *1220 * @param dest always set at least to NULL1221 * @parm converted_size set to the number of bytes occupied by the string in1222 * the destination on success.1223 *1224 * @return true if new buffer was correctly allocated, and string was1225 * 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 bytes1245 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;1307 309 } 1308 310 … … 1321 323 **/ 1322 324 1323 s ize_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)325 static 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) 1329 331 { 1330 332 char *dest; … … 1345 347 } 1346 348 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 1347 354 if (ucs2_align(base_ptr, src, flags)) { 1348 355 src = (const void *)((const char *)src + 1); 1349 if (src_len != (size_t)-1) 1350 src_len--; 356 src_len--; 1351 357 ucs2_align_len = 1; 1352 358 } … … 1354 360 if (flags & STR_TERMINATE) { 1355 361 /* 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 1369 368 /* Ensure we don't use an insane length from the client. */ 1370 369 if (src_len >= 1024*1024) { 1371 370 smb_panic("Bad src length in pull_ucs2_base_talloc\n"); 1372 371 } 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 } 1384 373 1385 374 /* ucs2 is always a multiple of 2 bytes */ … … 1387 376 1388 377 if (!convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, src, src_len, 1389 (void *)&dest, &dest_len , True)) {378 (void *)&dest, &dest_len)) { 1390 379 dest_len = 0; 1391 380 } … … 1398 387 if (size <= dest_len) { 1399 388 /* No, realloc. */ 1400 dest = TALLOC_REALLOC_ARRAY(ctx, dest, char,389 dest = talloc_realloc(ctx, dest, char, 1401 390 dest_len+1); 1402 391 if (!dest) { … … 1416 405 *ppdest = dest; 1417 406 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 talloc1427 *1428 * @param dest always set at least to NULL1429 * @parm converted_size set to the number of bytes occupied by the string in1430 * the destination on success.1431 *1432 * @return true if new buffer was correctly allocated, and string was1433 * 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 talloc1448 *1449 * @param dest always set at least to NULL1450 * @parm converted_size set to the number of bytes occupied by the string in1451 * the destination on success.1452 *1453 * @return true if new buffer was correctly allocated, and string was1454 * 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 talloc1470 *1471 * @param dest always set at least to NULL1472 * @parm converted_size set to the number of bytes occupied by the string in1473 * the destination on success.1474 *1475 * @return true if new buffer was correctly allocated, and string was1476 * 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);1487 407 } 1488 408 … … 1501 421 **/ 1502 422 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 423 size_t push_string_check_fn(void *dest, const char *src, 424 size_t dest_len, int flags) 425 { 1521 426 if (!(flags & STR_ASCII) && (flags & STR_UNICODE)) { 1522 427 return push_ucs2(NULL, dest, src, dest_len, flags); … … 1540 445 **/ 1541 446 1542 size_t push_string_base(const char *function, unsigned int line, 1543 const char *base, uint16 flags2, 447 size_t push_string_base(const char *base, uint16_t flags2, 1544 448 void *dest, const char *src, 1545 449 size_t dest_len, int flags) 1546 450 { 1547 #ifdef DEVELOPER1548 /* We really need to zero fill here, not clobber1549 * region, as we want to ensure that valgrind thinks1550 * all of the outgoing buffer has been written to1551 * so a send() or write() won't trap an error.1552 * JRA.1553 */1554 #if 01555 clobber_region(function, line, dest, dest_len);1556 #else1557 memset(dest, '\0', dest_len);1558 #endif1559 #endif1560 451 1561 452 if (!(flags & STR_ASCII) && \ … … 1565 456 } 1566 457 return push_ascii(dest, src, dest_len, flags); 1567 }1568 1569 /**1570 Copy a string from a char* src to a unicode or ascii1571 dos codepage destination choosing unicode or ascii based on the1572 flags supplied1573 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_len1580 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 DEVELOPER1587 /* We really need to zero fill here, not clobber1588 * region, as we want to ensure that valgrind thinks1589 * all of the outgoing buffer has been written to1590 * so a send() or write() won't trap an error.1591 * JRA.1592 */1593 memset(dest, '\0', dest_len);1594 #endif1595 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 on1610 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 -11617 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 DEVELOPER1633 clobber_region(function, line, dest, dest_len);1634 #endif1635 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);1647 458 } 1648 459 … … 1662 473 **/ 1663 474 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) 475 size_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) 1673 482 { 1674 483 if ((base_ptr == NULL) && ((flags & (STR_ASCII|STR_UNICODE)) == 0)) { … … 1694 503 } 1695 504 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 516 size_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 528 int 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.