2 Unix SMB/CIFS implementation.
3 Character set conversion Extensions
4 Copyright (C) Igor Vergeichik <iverg@mail.ru> 2001
5 Copyright (C) Andrew Tridgell 2001
6 Copyright (C) Simo Sorce 2001
7 Copyright (C) Martin Pool 2003
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
28 * @brief Character-set conversion routines built on our iconv.
30 * @note Samba's internal character set (at least in the 3.0 series)
31 * is always the same as the one for the Unix filesystem. It is
32 * <b>not</b> necessarily UTF-8 and may be different on machines that
33 * need i18n filenames to be compatible with Unix software. It does
34 * have to be a superset of ASCII. All multibyte sequences must start
35 * with a byte with the high bit set.
41 static bool initialized;
43 void lazy_initialize_conv(void)
46 load_case_tables_library();
53 * Destroy global objects allocated by init_iconv()
55 void gfree_charcnv(void)
57 TALLOC_FREE(global_iconv_handle);
62 * Initialize iconv conversion descriptors.
64 * This is called the first time it is needed, and also called again
65 * every time the configuration is reloaded, because the charset or
66 * codepage might have changed.
70 global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
71 lp_unix_charset(), lp_display_charset(),
72 true, global_iconv_handle);
76 * Convert string from one encoding to another, making error checking etc
77 * Slow path version - uses (slow) iconv.
79 * @param src pointer to source string (multibyte or singlebyte)
80 * @param srclen length of the source string in bytes
81 * @param dest pointer to destination string (multibyte or singlebyte)
82 * @param destlen maximal length allowed for string
83 * @returns the number of bytes occupied in the destination
85 * Ensure the srclen contains the terminating zero.
89 static size_t convert_string_internal(charset_t from, charset_t to,
90 void const *src, size_t srclen,
91 void *dest, size_t destlen, size_t *converted_size)
95 const char* inbuf = (const char*)src;
96 char* outbuf = (char*)dest;
97 smb_iconv_t descriptor;
98 struct smb_iconv_handle *ic;
100 lazy_initialize_conv();
101 ic = get_iconv_handle();
102 descriptor = get_conv_handle(ic, from, to);
104 if (srclen == (size_t)-1) {
105 if (from == CH_UTF16LE || from == CH_UTF16BE) {
106 srclen = (strlen_w((const smb_ucs2_t *)src)+1) * 2;
108 srclen = strlen((const char *)src)+1;
113 if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
121 retval = smb_iconv(descriptor, &inbuf, &i_len, &outbuf, &o_len);
122 if (converted_size != NULL)
123 *converted_size = destlen-o_len;
128 * Convert string from one encoding to another, making error checking etc
129 * Fast path version - handles ASCII first.
131 * @param src pointer to source string (multibyte or singlebyte)
132 * @param srclen length of the source string in bytes, or -1 for nul terminated.
133 * @param dest pointer to destination string (multibyte or singlebyte)
134 * @param destlen maximal length allowed for string - *NEVER* -1.
135 * @returns the number of bytes occupied in the destination
137 * Ensure the srclen contains the terminating zero.
139 * This function has been hand-tuned to provide a fast path.
140 * Don't change unless you really know what you are doing. JRA.
143 size_t convert_string_error(charset_t from, charset_t to,
144 void const *src, size_t srclen,
145 void *dest, size_t destlen,
146 size_t *converted_size)
149 * NB. We deliberately don't do a strlen here if srclen == -1.
150 * This is very expensive over millions of calls and is taken
151 * care of in the slow path in convert_string_internal. JRA.
155 SMB_ASSERT(destlen != (size_t)-1);
158 if (converted_size) {
165 if (from != CH_UTF16LE && from != CH_UTF16BE && to != CH_UTF16LE && to != CH_UTF16BE) {
166 const unsigned char *p = (const unsigned char *)src;
167 unsigned char *q = (unsigned char *)dest;
168 size_t slen = srclen;
169 size_t dlen = destlen;
170 unsigned char lastp = '\0';
173 /* If all characters are ascii, fast path here. */
174 while (slen && dlen) {
175 if ((lastp = *p) <= 0x7f) {
177 if (slen != (size_t)-1) {
185 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
188 size_t ret = convert_string_internal(from, to, p, slen, q, dlen, converted_size);
189 if (converted_size) {
190 *converted_size = ret + retval;
196 if (converted_size) {
197 *converted_size = retval;
200 /* Even if we fast path we should note if we ran out of room. */
201 if (((slen != (size_t)-1) && slen) ||
202 ((slen == (size_t)-1) && lastp)) {
208 } else if (from == CH_UTF16LE && to != CH_UTF16LE) {
209 const unsigned char *p = (const unsigned char *)src;
210 unsigned char *q = (unsigned char *)dest;
212 size_t slen = srclen;
213 size_t dlen = destlen;
214 unsigned char lastp = '\0';
216 /* If all characters are ascii, fast path here. */
217 while (((slen == (size_t)-1) || (slen >= 2)) && dlen) {
218 if (((lastp = *p) <= 0x7f) && (p[1] == 0)) {
220 if (slen != (size_t)-1) {
229 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
232 size_t ret = convert_string_internal(from, to, p, slen, q, dlen, converted_size);
233 if (converted_size) {
234 *converted_size = ret + retval;
240 if (converted_size) {
241 *converted_size = retval;
244 /* Even if we fast path we should note if we ran out of room. */
245 if (((slen != (size_t)-1) && slen) ||
246 ((slen == (size_t)-1) && lastp)) {
252 } else if (from != CH_UTF16LE && from != CH_UTF16BE && to == CH_UTF16LE) {
253 const unsigned char *p = (const unsigned char *)src;
254 unsigned char *q = (unsigned char *)dest;
256 size_t slen = srclen;
257 size_t dlen = destlen;
258 unsigned char lastp = '\0';
260 /* If all characters are ascii, fast path here. */
261 while (slen && (dlen >= 2)) {
262 if ((lastp = *p) <= 0x7F) {
265 if (slen != (size_t)-1) {
273 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
276 size_t ret = convert_string_internal(from, to, p, slen, q, dlen, converted_size);
277 if (converted_size) {
278 *converted_size = ret + retval;
284 if (converted_size) {
285 *converted_size = retval;
288 /* Even if we fast path we should note if we ran out of room. */
289 if (((slen != (size_t)-1) && slen) ||
290 ((slen == (size_t)-1) && lastp)) {
298 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
301 return convert_string_internal(from, to, src, srclen, dest, destlen, converted_size);
304 size_t convert_string(charset_t from, charset_t to,
305 void const *src, size_t srclen,
306 void *dest, size_t destlen) {
307 size_t converted_size;
308 size_t retval = convert_string_error(from, to, src, srclen, dest, destlen, &converted_size);
309 if(retval==(size_t)-1) {
310 const char *reason="unknown error";
313 reason="Incomplete multibyte sequence";
314 DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",
315 reason, (const char *)src));
319 struct smb_iconv_handle *ic;
320 lazy_initialize_conv();
321 ic = get_iconv_handle();
323 reason="No more room";
324 if (from == CH_UNIX) {
325 DEBUG(3,("E2BIG: convert_string(%s,%s): srclen=%u destlen=%u - '%s'\n",
326 charset_name(ic, from), charset_name(ic, to),
327 (unsigned int)srclen, (unsigned int)destlen, (const char *)src));
329 DEBUG(3,("E2BIG: convert_string(%s,%s): srclen=%u destlen=%u\n",
330 charset_name(ic, from), charset_name(ic, to),
331 (unsigned int)srclen, (unsigned int)destlen));
336 reason="Illegal multibyte sequence";
337 DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",
338 reason, (const char *)src));
341 DEBUG(0,("convert_string_internal: Conversion error: %s(%s)\n",
342 reason, (const char *)src));
345 /* smb_panic(reason); */
347 return converted_size;
352 * Convert between character sets, allocating a new buffer using talloc for the result.
354 * @param srclen length of source buffer.
355 * @param dest always set at least to NULL
356 * @parm converted_size set to the number of bytes occupied by the string in
357 * the destination on success.
358 * @note -1 is not accepted for srclen.
360 * @return true if new buffer was correctly allocated, and string was
363 * Ensure the srclen contains the terminating zero.
365 * I hate the goto's in this function. It's embarressing.....
366 * There has to be a cleaner way to do this. JRA.
368 bool convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to,
369 void const *src, size_t srclen, void *dst,
370 size_t *converted_size)
373 size_t i_len, o_len, destlen = (srclen * 3) / 2;
375 const char *inbuf = (const char *)src;
376 char *outbuf = NULL, *ob = NULL;
377 smb_iconv_t descriptor;
378 void **dest = (void **)dst;
379 struct smb_iconv_handle *ic;
383 if (!converted_size) {
388 if (src == NULL || srclen == (size_t)-1) {
394 /* We really should treat this as an error, but
395 there are too many callers that need this to
396 return a NULL terminated string in the correct
398 if (to == CH_UTF16LE|| to == CH_UTF16BE || to == CH_UTF16MUNGED) {
403 ob = talloc_zero_array(ctx, char, destlen);
408 *converted_size = destlen;
413 lazy_initialize_conv();
414 ic = get_iconv_handle();
415 descriptor = get_conv_handle(ic, from, to);
417 if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
418 DEBUG(0,("convert_string_talloc: Conversion not supported.\n"));
425 /* +2 is for ucs2 null termination. */
426 if ((destlen*2)+2 < destlen) {
427 /* wrapped ! abort. */
428 DEBUG(0, ("convert_string_talloc: destlen wrapped !\n"));
433 destlen = destlen * 2;
436 /* +2 is for ucs2 null termination. */
437 ob = (char *)TALLOC_REALLOC(ctx, ob, destlen + 2);
440 DEBUG(0, ("convert_string_talloc: realloc failed!\n"));
448 retval = smb_iconv(descriptor,
451 if(retval == (size_t)-1) {
452 const char *reason="unknown error";
455 reason="Incomplete multibyte sequence";
456 DEBUG(3,("convert_string_talloc: Conversion error: %s(%s)\n",reason,inbuf));
461 reason="Illegal multibyte sequence";
462 DEBUG(3,("convert_string_talloc: Conversion error: %s(%s)\n",reason,inbuf));
465 DEBUG(0,("Conversion error: %s(%s)\n",reason,inbuf));
466 /* smb_panic(reason); */
471 destlen = destlen - o_len;
472 /* Don't shrink unless we're reclaiming a lot of
473 * space. This is in the hot codepath and these
474 * reallocs *cost*. JRA.
477 /* We're shrinking here so we know the +2 is safe from wrap. */
478 ob = (char *)TALLOC_REALLOC(ctx,ob,destlen + 2);
481 if (destlen && !ob) {
482 DEBUG(0, ("convert_string_talloc: out of memory!\n"));
489 /* Must ucs2 null terminate in the extra space we allocated. */
491 ob[destlen+1] = '\0';
493 /* Ensure we can never return a *converted_size of zero. */
495 /* As we're now returning false on a bad smb_iconv call,
496 this should never happen. But be safe anyway. */
497 if (to == CH_UTF16LE|| to == CH_UTF16BE || to == CH_UTF16MUNGED) {
504 *converted_size = destlen;
508 size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
513 if (!push_ucs2_talloc(talloc_tos(), &buffer, src, &size)) {
517 if (!strupper_w(buffer) && (dest == src)) {
522 size = convert_string(CH_UTF16LE, CH_UNIX, buffer, size, dest, destlen);
528 talloc_strdup() a unix string to upper case.
531 char *talloc_strdup_upper(TALLOC_CTX *ctx, const char *s)
533 char *out_buffer = talloc_strdup(ctx,s);
534 const unsigned char *p = (const unsigned char *)s;
535 unsigned char *q = (unsigned char *)out_buffer;
541 /* this is quite a common operation, so we want it to be
542 fast. We optimise for the ascii case, knowing that all our
543 supported multi-byte character sets are ascii-compatible
544 (ie. they match for the first 128 chars) */
549 *q++ = toupper_ascii_fast(*p);
555 size_t converted_size, converted_size2;
556 smb_ucs2_t *ubuf = NULL;
558 /* We're not using the ascii buffer above. */
559 TALLOC_FREE(out_buffer);
561 if (!convert_string_talloc(ctx, CH_UNIX, CH_UTF16LE, s,
562 strlen(s)+1, (void *)&ubuf,
570 if (!convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, ubuf,
571 converted_size, (void *)&out_buffer,
578 /* Don't need the intermediate buffer
587 char *strupper_talloc(TALLOC_CTX *ctx, const char *s) {
588 return talloc_strdup_upper(ctx, s);
592 size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
595 smb_ucs2_t *buffer = NULL;
597 if (!convert_string_talloc(talloc_tos(), CH_UNIX, CH_UTF16LE, src, srclen,
598 (void **)(void *)&buffer, &size))
600 smb_panic("failed to create UCS2 buffer");
602 if (!strlower_w(buffer) && (dest == src)) {
606 size = convert_string(CH_UTF16LE, CH_UNIX, buffer, size, dest, destlen);
612 char *talloc_strdup_lower(TALLOC_CTX *ctx, const char *s)
614 size_t converted_size;
615 smb_ucs2_t *buffer = NULL;
618 if (!push_ucs2_talloc(ctx, &buffer, s, &converted_size)) {
624 if (!pull_ucs2_talloc(ctx, &out_buffer, buffer, &converted_size)) {
634 char *strlower_talloc(TALLOC_CTX *ctx, const char *s) {
635 return talloc_strdup_lower(ctx, s);
638 size_t ucs2_align(const void *base_ptr, const void *p, int flags)
640 if (flags & (STR_NOALIGN|STR_ASCII))
642 return PTR_DIFF(p, base_ptr) & 1;
647 * Copy a string from a char* unix src to a dos codepage string destination.
649 * @return the number of bytes occupied by the string in the destination.
651 * @param flags can include
653 * <dt>STR_TERMINATE</dt> <dd>means include the null termination</dd>
654 * <dt>STR_UPPER</dt> <dd>means uppercase in the destination</dd>
657 * @param dest_len the maximum length in bytes allowed in the
660 size_t push_ascii(void *dest, const char *src, size_t dest_len, int flags)
662 size_t src_len = strlen(src);
666 /* No longer allow a length of -1. */
667 if (dest_len == (size_t)-1) {
668 smb_panic("push_ascii - dest_len == -1");
671 if (flags & STR_UPPER) {
672 tmpbuf = SMB_STRDUP(src);
674 smb_panic("malloc fail");
680 if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII)) {
684 ret = convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len);
685 if (ret == (size_t)-1 &&
686 (flags & (STR_TERMINATE | STR_TERMINATE_ASCII))
688 ((char *)dest)[0] = '\0';
694 /********************************************************************
695 Push and malloc an ascii string. src and dest null terminated.
696 ********************************************************************/
698 bool push_ascii_talloc(TALLOC_CTX *mem_ctx, char **dest, const char *src, size_t *converted_size)
700 size_t src_len = strlen(src)+1;
703 return convert_string_talloc(mem_ctx, CH_UNIX, CH_DOS, src, src_len,
704 (void **)dest, converted_size);
708 * Copy a string from a dos codepage source to a unix char* destination.
710 * The resulting string in "dest" is always null terminated.
712 * @param flags can have:
714 * <dt>STR_TERMINATE</dt>
715 * <dd>STR_TERMINATE means the string in @p src
716 * is null terminated, and src_len is ignored.</dd>
719 * @param src_len is the length of the source area in bytes.
720 * @returns the number of bytes occupied by the string in @p src.
722 size_t pull_ascii(char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
726 if (dest_len == (size_t)-1) {
727 /* No longer allow dest_len of -1. */
728 smb_panic("pull_ascii - invalid dest_len of -1");
731 if (flags & STR_TERMINATE) {
732 if (src_len == (size_t)-1) {
733 src_len = strlen((const char *)src) + 1;
735 size_t len = strnlen((const char *)src, src_len);
742 ret = convert_string(CH_DOS, CH_UNIX, src, src_len, dest, dest_len);
743 if (ret == (size_t)-1) {
748 if (dest_len && ret) {
749 /* Did we already process the terminating zero ? */
750 if (dest[MIN(ret-1, dest_len-1)] != 0) {
751 dest[MIN(ret, dest_len-1)] = 0;
761 * Copy a string from a dos codepage source to a unix char* destination.
764 * The resulting string in "dest" is always null terminated.
766 * @param flags can have:
768 * <dt>STR_TERMINATE</dt>
769 * <dd>STR_TERMINATE means the string in @p src
770 * is null terminated, and src_len is ignored.</dd>
773 * @param src_len is the length of the source area in bytes.
774 * @returns the number of bytes occupied by the string in @p src.
777 static size_t pull_ascii_base_talloc(TALLOC_CTX *ctx,
792 if (src_len == (size_t)-1) {
793 smb_panic("sec_len == -1 in pull_ascii_base_talloc");
796 if (flags & STR_TERMINATE) {
797 size_t len = strnlen((const char *)src, src_len);
801 /* Ensure we don't use an insane length from the client. */
802 if (src_len >= 1024*1024) {
803 char *msg = talloc_asprintf(ctx,
804 "Bad src length (%u) in "
805 "pull_ascii_base_talloc",
806 (unsigned int)src_len);
811 /* src_len != -1 here. */
813 if (!convert_string_talloc(ctx, CH_DOS, CH_UNIX, src, src_len, &dest,
818 if (dest_len && dest) {
819 /* Did we already process the terminating zero ? */
820 if (dest[dest_len-1] != 0) {
821 size_t size = talloc_get_size(dest);
822 /* Have we got space to append the '\0' ? */
823 if (size <= dest_len) {
825 dest = TALLOC_REALLOC_ARRAY(ctx, dest, char,
829 dest_len = (size_t)-1;
834 dest[dest_len] = '\0';
846 * Copy a string from a char* src to a unicode destination.
848 * @returns the number of bytes occupied by the string in the destination.
850 * @param flags can have:
853 * <dt>STR_TERMINATE <dd>means include the null termination.
854 * <dt>STR_UPPER <dd>means uppercase in the destination.
855 * <dt>STR_NOALIGN <dd>means don't do alignment.
858 * @param dest_len is the maximum length allowed in the
862 size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_len, int flags)
868 if (dest_len == (size_t)-1) {
869 /* No longer allow dest_len of -1. */
870 smb_panic("push_ucs2 - invalid dest_len of -1");
873 if (flags & STR_TERMINATE)
874 src_len = (size_t)-1;
876 src_len = strlen(src);
878 if (ucs2_align(base_ptr, dest, flags)) {
880 dest = (void *)((char *)dest + 1);
886 /* ucs2 is always a multiple of 2 bytes */
889 ret = convert_string(CH_UNIX, CH_UTF16LE, src, src_len, dest, dest_len);
890 if (ret == (size_t)-1) {
891 if ((flags & STR_TERMINATE) &&
901 if (flags & STR_UPPER) {
902 smb_ucs2_t *dest_ucs2 = (smb_ucs2_t *)dest;
905 /* We check for i < (ret / 2) below as the dest string isn't null
906 terminated if STR_TERMINATE isn't set. */
908 for (i = 0; i < (ret / 2) && i < (dest_len / 2) && dest_ucs2[i]; i++) {
909 smb_ucs2_t v = toupper_m(dest_ucs2[i]);
910 if (v != dest_ucs2[i]) {
921 * Copy a string from a unix char* src to a UCS2 destination,
922 * allocating a buffer using talloc().
924 * @param dest always set at least to NULL
925 * @parm converted_size set to the number of bytes occupied by the string in
926 * the destination on success.
928 * @return true if new buffer was correctly allocated, and string was
931 bool push_ucs2_talloc(TALLOC_CTX *ctx, smb_ucs2_t **dest, const char *src,
932 size_t *converted_size)
934 size_t src_len = strlen(src)+1;
937 return convert_string_talloc(ctx, CH_UNIX, CH_UTF16LE, src, src_len,
938 (void **)dest, converted_size);
943 * Copy a string from a unix char* src to a UTF-8 destination, allocating a buffer using talloc
945 * @param dest always set at least to NULL
946 * @parm converted_size set to the number of bytes occupied by the string in
947 * the destination on success.
949 * @return true if new buffer was correctly allocated, and string was
953 bool push_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src,
954 size_t *converted_size)
956 size_t src_len = strlen(src)+1;
959 return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len,
960 (void**)dest, converted_size);
964 Copy a string from a ucs2 source to a unix char* destination.
966 STR_TERMINATE means the string in src is null terminated.
967 STR_NOALIGN means don't try to align.
968 if STR_TERMINATE is set then src_len is ignored if it is -1.
969 src_len is the length of the source area in bytes
970 Return the number of bytes occupied by the string in src.
971 The resulting string in "dest" is always null terminated.
974 size_t pull_ucs2(const void *base_ptr, char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
977 size_t ucs2_align_len = 0;
979 if (dest_len == (size_t)-1) {
980 /* No longer allow dest_len of -1. */
981 smb_panic("pull_ucs2 - invalid dest_len of -1");
985 if (dest && dest_len > 0) {
991 if (ucs2_align(base_ptr, src, flags)) {
992 src = (const void *)((const char *)src + 1);
993 if (src_len != (size_t)-1)
998 if (flags & STR_TERMINATE) {
999 /* src_len -1 is the default for null terminated strings. */
1000 if (src_len != (size_t)-1) {
1001 size_t len = strnlen_w((const smb_ucs2_t *)src,
1003 if (len < src_len/2)
1009 /* ucs2 is always a multiple of 2 bytes */
1010 if (src_len != (size_t)-1)
1013 ret = convert_string(CH_UTF16LE, CH_UNIX, src, src_len, dest, dest_len);
1014 if (ret == (size_t)-1) {
1019 if (src_len == (size_t)-1)
1022 if (dest_len && ret) {
1023 /* Did we already process the terminating zero ? */
1024 if (dest[MIN(ret-1, dest_len-1)] != 0) {
1025 dest[MIN(ret, dest_len-1)] = 0;
1031 return src_len + ucs2_align_len;
1035 Copy a string from a ucs2 source to a unix char* destination.
1036 Talloc version with a base pointer.
1037 Uses malloc if TALLOC_CTX is NULL (this is a bad interface and
1040 STR_TERMINATE means the string in src is null terminated.
1041 STR_NOALIGN means don't try to align.
1042 if STR_TERMINATE is set then src_len is ignored if it is -1.
1043 src_len is the length of the source area in bytes
1044 Return the number of bytes occupied by the string in src.
1045 The resulting string in "dest" is always null terminated.
1048 static size_t pull_ucs2_base_talloc(TALLOC_CTX *ctx,
1049 const void *base_ptr,
1057 size_t ucs2_align_len = 0;
1062 /* Ensure we never use the braindead "malloc" varient. */
1064 smb_panic("NULL talloc CTX in pull_ucs2_base_talloc\n");
1072 if (src_len == (size_t)-1) {
1073 /* no longer used anywhere, but worth checking */
1074 smb_panic("sec_len == -1 in pull_ucs2_base_talloc");
1077 if (ucs2_align(base_ptr, src, flags)) {
1078 src = (const void *)((const char *)src + 1);
1083 if (flags & STR_TERMINATE) {
1084 /* src_len -1 is the default for null terminated strings. */
1085 size_t len = strnlen_w((const smb_ucs2_t *)src,
1087 if (len < src_len/2)
1091 /* Ensure we don't use an insane length from the client. */
1092 if (src_len >= 1024*1024) {
1093 smb_panic("Bad src length in pull_ucs2_base_talloc\n");
1097 /* ucs2 is always a multiple of 2 bytes */
1100 if (!convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, src, src_len,
1101 (void *)&dest, &dest_len)) {
1106 /* Did we already process the terminating zero ? */
1107 if (dest[dest_len-1] != 0) {
1108 size_t size = talloc_get_size(dest);
1109 /* Have we got space to append the '\0' ? */
1110 if (size <= dest_len) {
1112 dest = TALLOC_REALLOC_ARRAY(ctx, dest, char,
1116 dest_len = (size_t)-1;
1121 dest[dest_len] = '\0';
1129 return src_len + ucs2_align_len;
1133 * Copy a string from a UCS2 src to a unix char * destination, allocating a buffer using talloc
1135 * @param dest always set at least to NULL
1136 * @parm converted_size set to the number of bytes occupied by the string in
1137 * the destination on success.
1139 * @return true if new buffer was correctly allocated, and string was
1143 bool pull_ucs2_talloc(TALLOC_CTX *ctx, char **dest, const smb_ucs2_t *src,
1144 size_t *converted_size)
1146 size_t src_len = (strlen_w(src)+1) * sizeof(smb_ucs2_t);
1149 return convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, src, src_len,
1150 (void **)dest, converted_size);
1154 * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer using talloc
1156 * @param dest always set at least to NULL
1157 * @parm converted_size set to the number of bytes occupied by the string in
1158 * the destination on success.
1160 * @return true if new buffer was correctly allocated, and string was
1164 bool pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src,
1165 size_t *converted_size)
1167 size_t src_len = strlen(src)+1;
1170 return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len,
1171 (void **)dest, converted_size);
1176 * Copy a string from a DOS src to a unix char * destination, allocating a buffer using talloc
1178 * @param dest always set at least to NULL
1179 * @parm converted_size set to the number of bytes occupied by the string in
1180 * the destination on success.
1182 * @return true if new buffer was correctly allocated, and string was
1186 bool pull_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src,
1187 size_t *converted_size)
1189 size_t src_len = strlen(src)+1;
1192 return convert_string_talloc(ctx, CH_DOS, CH_UNIX, src, src_len,
1193 (void **)dest, converted_size);
1197 Copy a string from a char* src to a unicode or ascii
1198 dos codepage destination choosing unicode or ascii based on the
1200 Return the number of bytes occupied by the string in the destination.
1202 STR_TERMINATE means include the null termination.
1203 STR_UPPER means uppercase in the destination.
1204 STR_ASCII use ascii even with unicode packet.
1205 STR_NOALIGN means don't do alignment.
1206 dest_len is the maximum length allowed in the destination. If dest_len
1207 is -1 then no maxiumum is used.
1210 size_t push_string_check_fn(void *dest, const char *src,
1211 size_t dest_len, int flags)
1213 if (!(flags & STR_ASCII) && (flags & STR_UNICODE)) {
1214 return push_ucs2(NULL, dest, src, dest_len, flags);
1216 return push_ascii(dest, src, dest_len, flags);
1221 Copy a string from a char* src to a unicode or ascii
1222 dos codepage destination choosing unicode or ascii based on the
1223 flags in the SMB buffer starting at base_ptr.
1224 Return the number of bytes occupied by the string in the destination.
1226 STR_TERMINATE means include the null termination.
1227 STR_UPPER means uppercase in the destination.
1228 STR_ASCII use ascii even with unicode packet.
1229 STR_NOALIGN means don't do alignment.
1230 dest_len is the maximum length allowed in the destination. If dest_len
1231 is -1 then no maxiumum is used.
1234 size_t push_string_base(const char *base, uint16 flags2,
1235 void *dest, const char *src,
1236 size_t dest_len, int flags)
1239 if (!(flags & STR_ASCII) && \
1240 ((flags & STR_UNICODE || \
1241 (flags2 & FLAGS2_UNICODE_STRINGS)))) {
1242 return push_ucs2(base, dest, src, dest_len, flags);
1244 return push_ascii(dest, src, dest_len, flags);
1248 Copy a string from a char* src to a unicode or ascii
1249 dos codepage destination choosing unicode or ascii based on the
1251 Return the number of bytes occupied by the string in the destination.
1253 STR_TERMINATE means include the null termination.
1254 STR_UPPER means uppercase in the destination.
1255 STR_ASCII use ascii even with unicode packet.
1256 STR_NOALIGN means don't do alignment.
1257 dest_len is the maximum length allowed in the destination. If dest_len
1258 is -1 then no maxiumum is used.
1261 ssize_t push_string(void *dest, const char *src, size_t dest_len, int flags)
1265 if (!(flags & STR_ASCII) && \
1266 (flags & STR_UNICODE)) {
1267 ret = push_ucs2(NULL, dest, src, dest_len, flags);
1269 ret = push_ascii(dest, src, dest_len, flags);
1271 if (ret == (size_t)-1) {
1278 Copy a string from a unicode or ascii source (depending on
1279 the packet flags) to a char* destination.
1281 STR_TERMINATE means the string in src is null terminated.
1282 STR_UNICODE means to force as unicode.
1283 STR_ASCII use ascii even with unicode packet.
1284 STR_NOALIGN means don't do alignment.
1285 if STR_TERMINATE is set then src_len is ignored is it is -1
1286 src_len is the length of the source area in bytes.
1287 Return the number of bytes occupied by the string in src.
1288 The resulting string in "dest" is always null terminated.
1291 size_t pull_string_fn(const void *base_ptr,
1299 if ((base_ptr == NULL) && ((flags & (STR_ASCII|STR_UNICODE)) == 0)) {
1300 smb_panic("No base ptr to get flg2 and neither ASCII nor "
1304 if (!(flags & STR_ASCII) && \
1305 ((flags & STR_UNICODE || \
1306 (smb_flags2 & FLAGS2_UNICODE_STRINGS)))) {
1307 return pull_ucs2(base_ptr, dest, src, dest_len, src_len, flags);
1309 return pull_ascii(dest, src, dest_len, src_len, flags);
1313 Copy a string from a unicode or ascii source (depending on
1314 the packet flags) to a char* destination.
1315 Variant that uses talloc.
1317 STR_TERMINATE means the string in src is null terminated.
1318 STR_UNICODE means to force as unicode.
1319 STR_ASCII use ascii even with unicode packet.
1320 STR_NOALIGN means don't do alignment.
1321 if STR_TERMINATE is set then src_len is ignored is it is -1
1322 src_len is the length of the source area in bytes.
1323 Return the number of bytes occupied by the string in src.
1324 The resulting string in "dest" is always null terminated.
1327 size_t pull_string_talloc(TALLOC_CTX *ctx,
1328 const void *base_ptr,
1335 if ((base_ptr == NULL) && ((flags & (STR_ASCII|STR_UNICODE)) == 0)) {
1336 smb_panic("No base ptr to get flg2 and neither ASCII nor "
1340 if (!(flags & STR_ASCII) && \
1341 ((flags & STR_UNICODE || \
1342 (smb_flags2 & FLAGS2_UNICODE_STRINGS)))) {
1343 return pull_ucs2_base_talloc(ctx,
1350 return pull_ascii_base_talloc(ctx,
1358 size_t align_string(const void *base_ptr, const char *p, int flags)
1360 if (!(flags & STR_ASCII) && \
1361 ((flags & STR_UNICODE || \
1362 (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) {
1363 return ucs2_align(base_ptr, p, flags);