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/>.
25 /* We can parameterize this if someone complains.... JRA. */
27 char lp_failed_convert_char(void)
35 * @brief Character-set conversion routines built on our iconv.
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.
48 static bool initialized;
50 void lazy_initialize_conv(void)
53 load_case_tables_library();
60 * Destroy global objects allocated by init_iconv()
62 void gfree_charcnv(void)
64 TALLOC_FREE(global_iconv_handle);
69 * Initialize iconv conversion descriptors.
71 * This is called the first time it is needed, and also called again
72 * every time the configuration is reloaded, because the charset or
73 * codepage might have changed.
77 global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
78 lp_unix_charset(), lp_display_charset(),
79 true, global_iconv_handle);
83 * Convert string from one encoding to another, making error checking etc
84 * Slow path version - uses (slow) iconv.
86 * @param src pointer to source string (multibyte or singlebyte)
87 * @param srclen length of the source string in bytes
88 * @param dest pointer to destination string (multibyte or singlebyte)
89 * @param destlen maximal length allowed for string
90 * @returns the number of bytes occupied in the destination
92 * Ensure the srclen contains the terminating zero.
96 static size_t convert_string_internal(charset_t from, charset_t to,
97 void const *src, size_t srclen,
98 void *dest, size_t destlen, size_t *converted_size)
102 const char* inbuf = (const char*)src;
103 char* outbuf = (char*)dest;
104 smb_iconv_t descriptor;
105 struct smb_iconv_handle *ic;
107 lazy_initialize_conv();
108 ic = get_iconv_handle();
109 descriptor = get_conv_handle(ic, from, to);
111 if (srclen == (size_t)-1) {
112 if (from == CH_UTF16LE || from == CH_UTF16BE) {
113 srclen = (strlen_w((const smb_ucs2_t *)src)+1) * 2;
115 srclen = strlen((const char *)src)+1;
120 if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
128 retval = smb_iconv(descriptor, &inbuf, &i_len, &outbuf, &o_len);
129 if (converted_size != NULL)
130 *converted_size = destlen-o_len;
135 * Convert string from one encoding to another, making error checking etc
136 * Fast path version - handles ASCII first.
138 * @param src pointer to source string (multibyte or singlebyte)
139 * @param srclen length of the source string in bytes, or -1 for nul terminated.
140 * @param dest pointer to destination string (multibyte or singlebyte)
141 * @param destlen maximal length allowed for string - *NEVER* -1.
142 * @returns the number of bytes occupied in the destination
144 * Ensure the srclen contains the terminating zero.
146 * This function has been hand-tuned to provide a fast path.
147 * Don't change unless you really know what you are doing. JRA.
150 size_t convert_string_error(charset_t from, charset_t to,
151 void const *src, size_t srclen,
152 void *dest, size_t destlen,
153 size_t *converted_size)
156 * NB. We deliberately don't do a strlen here if srclen == -1.
157 * This is very expensive over millions of calls and is taken
158 * care of in the slow path in convert_string_internal. JRA.
162 SMB_ASSERT(destlen != (size_t)-1);
165 if (converted_size) {
172 if (from != CH_UTF16LE && from != CH_UTF16BE && to != CH_UTF16LE && to != CH_UTF16BE) {
173 const unsigned char *p = (const unsigned char *)src;
174 unsigned char *q = (unsigned char *)dest;
175 size_t slen = srclen;
176 size_t dlen = destlen;
177 unsigned char lastp = '\0';
180 /* If all characters are ascii, fast path here. */
181 while (slen && dlen) {
182 if ((lastp = *p) <= 0x7f) {
184 if (slen != (size_t)-1) {
192 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
195 size_t ret = convert_string_internal(from, to, p, slen, q, dlen, converted_size);
196 if (converted_size) {
197 *converted_size += retval;
204 /* Even if we fast path we should note if we ran out of room. */
205 if (((slen != (size_t)-1) && slen) ||
206 ((slen == (size_t)-1) && lastp)) {
211 } else if (from == CH_UTF16LE && to != CH_UTF16LE) {
212 const unsigned char *p = (const unsigned char *)src;
213 unsigned char *q = (unsigned char *)dest;
215 size_t slen = srclen;
216 size_t dlen = destlen;
217 unsigned char lastp = '\0';
219 /* If all characters are ascii, fast path here. */
220 while (((slen == (size_t)-1) || (slen >= 2)) && dlen) {
221 if (((lastp = *p) <= 0x7f) && (p[1] == 0)) {
223 if (slen != (size_t)-1) {
232 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
235 size_t ret = convert_string_internal(from, to, p, slen, q, dlen, converted_size);
236 if (converted_size) {
237 *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)) {
251 } else if (from != CH_UTF16LE && from != CH_UTF16BE && to == CH_UTF16LE) {
252 const unsigned char *p = (const unsigned char *)src;
253 unsigned char *q = (unsigned char *)dest;
255 size_t slen = srclen;
256 size_t dlen = destlen;
257 unsigned char lastp = '\0';
259 /* If all characters are ascii, fast path here. */
260 while (slen && (dlen >= 2)) {
261 if ((lastp = *p) <= 0x7F) {
264 if (slen != (size_t)-1) {
272 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
275 size_t ret = convert_string_internal(from, to, p, slen, q, dlen, converted_size);
276 if (converted_size) {
277 *converted_size += retval;
283 if (converted_size) {
284 *converted_size += retval;
287 /* Even if we fast path we should note if we ran out of room. */
288 if (((slen != (size_t)-1) && slen) ||
289 ((slen == (size_t)-1) && lastp)) {
297 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
300 return convert_string_internal(from, to, src, srclen, dest, destlen, converted_size);
303 size_t convert_string(charset_t from, charset_t to,
304 void const *src, size_t srclen,
305 void *dest, size_t destlen) {
306 size_t converted_size;
307 size_t retval = convert_string_error(from, to, src, srclen, dest, destlen, &converted_size);
308 if(retval==(size_t)-1) {
309 const char *reason="unknown error";
312 reason="Incomplete multibyte sequence";
313 DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",reason,src));
317 struct smb_iconv_handle *ic;
318 lazy_initialize_conv();
319 ic = get_iconv_handle();
321 reason="No more room";
322 if (from == CH_UNIX) {
323 DEBUG(3,("E2BIG: convert_string(%s,%s): srclen=%u destlen=%u - '%s'\n",
324 charset_name(ic, from), charset_name(ic, to),
325 (unsigned int)srclen, (unsigned int)destlen, (const char *)src));
327 DEBUG(3,("E2BIG: convert_string(%s,%s): srclen=%u destlen=%u\n",
328 charset_name(ic, from), charset_name(ic, to),
329 (unsigned int)srclen, (unsigned int)destlen));
334 reason="Illegal multibyte sequence";
335 DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",reason,src));
338 DEBUG(0,("convert_string_internal: Conversion error: %s(%s)\n",reason,src));
341 /* smb_panic(reason); */
343 return converted_size;
348 * Convert between character sets, allocating a new buffer using talloc for the result.
350 * @param srclen length of source buffer.
351 * @param dest always set at least to NULL
352 * @parm converted_size set to the number of bytes occupied by the string in
353 * the destination on success.
354 * @note -1 is not accepted for srclen.
356 * @return true if new buffer was correctly allocated, and string was
359 * Ensure the srclen contains the terminating zero.
361 * I hate the goto's in this function. It's embarressing.....
362 * There has to be a cleaner way to do this. JRA.
364 bool convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to,
365 void const *src, size_t srclen, void *dst,
366 size_t *converted_size)
369 size_t i_len, o_len, destlen = (srclen * 3) / 2;
371 const char *inbuf = (const char *)src;
372 char *outbuf = NULL, *ob = NULL;
373 smb_iconv_t descriptor;
374 void **dest = (void **)dst;
375 struct smb_iconv_handle *ic;
379 if (!converted_size) {
384 if (src == NULL || srclen == (size_t)-1) {
389 ob = talloc_strdup(ctx, "");
399 lazy_initialize_conv();
400 ic = get_iconv_handle();
401 descriptor = get_conv_handle(ic, from, to);
403 if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
404 DEBUG(0,("convert_string_talloc: Conversion not supported.\n"));
411 /* +2 is for ucs2 null termination. */
412 if ((destlen*2)+2 < destlen) {
413 /* wrapped ! abort. */
414 DEBUG(0, ("convert_string_talloc: destlen wrapped !\n"));
419 destlen = destlen * 2;
422 /* +2 is for ucs2 null termination. */
423 ob = (char *)TALLOC_REALLOC(ctx, ob, destlen + 2);
426 DEBUG(0, ("convert_string_talloc: realloc failed!\n"));
434 retval = smb_iconv(descriptor,
437 if(retval == (size_t)-1) {
438 const char *reason="unknown error";
441 reason="Incomplete multibyte sequence";
442 DEBUG(3,("convert_string_talloc: Conversion error: %s(%s)\n",reason,inbuf));
447 reason="Illegal multibyte sequence";
448 DEBUG(3,("convert_string_talloc: Conversion error: %s(%s)\n",reason,inbuf));
451 DEBUG(0,("Conversion error: %s(%s)\n",reason,inbuf));
452 /* smb_panic(reason); */
457 destlen = destlen - o_len;
458 /* Don't shrink unless we're reclaiming a lot of
459 * space. This is in the hot codepath and these
460 * reallocs *cost*. JRA.
463 /* We're shrinking here so we know the +2 is safe from wrap. */
464 ob = (char *)TALLOC_REALLOC(ctx,ob,destlen + 2);
467 if (destlen && !ob) {
468 DEBUG(0, ("convert_string_talloc: out of memory!\n"));
475 /* Must ucs2 null terminate in the extra space we allocated. */
477 ob[destlen+1] = '\0';
479 *converted_size = destlen;
483 size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
488 if (!push_ucs2_talloc(talloc_tos(), &buffer, src, &size)) {
492 if (!strupper_w(buffer) && (dest == src)) {
497 size = convert_string(CH_UTF16LE, CH_UNIX, buffer, size, dest, destlen);
503 talloc_strdup() a unix string to upper case.
506 char *talloc_strdup_upper(TALLOC_CTX *ctx, const char *s)
508 char *out_buffer = talloc_strdup(ctx,s);
509 const unsigned char *p = (const unsigned char *)s;
510 unsigned char *q = (unsigned char *)out_buffer;
516 /* this is quite a common operation, so we want it to be
517 fast. We optimise for the ascii case, knowing that all our
518 supported multi-byte character sets are ascii-compatible
519 (ie. they match for the first 128 chars) */
524 *q++ = toupper_ascii_fast(*p);
530 size_t converted_size, converted_size2;
531 smb_ucs2_t *ubuf = NULL;
533 /* We're not using the ascii buffer above. */
534 TALLOC_FREE(out_buffer);
536 if (!convert_string_talloc(ctx, CH_UNIX, CH_UTF16LE, s,
537 strlen(s)+1, (void *)&ubuf,
545 if (!convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, ubuf,
546 converted_size, (void *)&out_buffer,
553 /* Don't need the intermediate buffer
562 char *strupper_talloc(TALLOC_CTX *ctx, const char *s) {
563 return talloc_strdup_upper(ctx, s);
567 size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
570 smb_ucs2_t *buffer = NULL;
572 if (!convert_string_talloc(talloc_tos(), CH_UNIX, CH_UTF16LE, src, srclen,
573 (void **)(void *)&buffer, &size))
575 smb_panic("failed to create UCS2 buffer");
577 if (!strlower_w(buffer) && (dest == src)) {
581 size = convert_string(CH_UTF16LE, CH_UNIX, buffer, size, dest, destlen);
587 char *talloc_strdup_lower(TALLOC_CTX *ctx, const char *s)
589 size_t converted_size;
590 smb_ucs2_t *buffer = NULL;
593 if (!push_ucs2_talloc(ctx, &buffer, s, &converted_size)) {
599 if (!pull_ucs2_talloc(ctx, &out_buffer, buffer, &converted_size)) {
609 char *strlower_talloc(TALLOC_CTX *ctx, const char *s) {
610 return talloc_strdup_lower(ctx, s);
613 size_t ucs2_align(const void *base_ptr, const void *p, int flags)
615 if (flags & (STR_NOALIGN|STR_ASCII))
617 return PTR_DIFF(p, base_ptr) & 1;
622 * Copy a string from a char* unix src to a dos codepage string destination.
624 * @return the number of bytes occupied by the string in the destination.
626 * @param flags can include
628 * <dt>STR_TERMINATE</dt> <dd>means include the null termination</dd>
629 * <dt>STR_UPPER</dt> <dd>means uppercase in the destination</dd>
632 * @param dest_len the maximum length in bytes allowed in the
635 size_t push_ascii(void *dest, const char *src, size_t dest_len, int flags)
637 size_t src_len = strlen(src);
641 /* No longer allow a length of -1. */
642 if (dest_len == (size_t)-1) {
643 smb_panic("push_ascii - dest_len == -1");
646 if (flags & STR_UPPER) {
647 tmpbuf = SMB_STRDUP(src);
649 smb_panic("malloc fail");
655 if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII)) {
659 ret = convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len);
660 if (ret == (size_t)-1 &&
661 (flags & (STR_TERMINATE | STR_TERMINATE_ASCII))
663 ((char *)dest)[0] = '\0';
669 /********************************************************************
670 Push and malloc an ascii string. src and dest null terminated.
671 ********************************************************************/
673 bool push_ascii_talloc(TALLOC_CTX *mem_ctx, char **dest, const char *src, size_t *converted_size)
675 size_t src_len = strlen(src)+1;
678 return convert_string_talloc(mem_ctx, CH_UNIX, CH_DOS, src, src_len,
679 (void **)dest, converted_size);
683 * Copy a string from a dos codepage source to a unix char* destination.
685 * The resulting string in "dest" is always null terminated.
687 * @param flags can have:
689 * <dt>STR_TERMINATE</dt>
690 * <dd>STR_TERMINATE means the string in @p src
691 * is null terminated, and src_len is ignored.</dd>
694 * @param src_len is the length of the source area in bytes.
695 * @returns the number of bytes occupied by the string in @p src.
697 size_t pull_ascii(char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
701 if (dest_len == (size_t)-1) {
702 /* No longer allow dest_len of -1. */
703 smb_panic("pull_ascii - invalid dest_len of -1");
706 if (flags & STR_TERMINATE) {
707 if (src_len == (size_t)-1) {
708 src_len = strlen((const char *)src) + 1;
710 size_t len = strnlen((const char *)src, src_len);
717 ret = convert_string(CH_DOS, CH_UNIX, src, src_len, dest, dest_len);
718 if (ret == (size_t)-1) {
723 if (dest_len && ret) {
724 /* Did we already process the terminating zero ? */
725 if (dest[MIN(ret-1, dest_len-1)] != 0) {
726 dest[MIN(ret, dest_len-1)] = 0;
736 * Copy a string from a dos codepage source to a unix char* destination.
739 * The resulting string in "dest" is always null terminated.
741 * @param flags can have:
743 * <dt>STR_TERMINATE</dt>
744 * <dd>STR_TERMINATE means the string in @p src
745 * is null terminated, and src_len is ignored.</dd>
748 * @param src_len is the length of the source area in bytes.
749 * @returns the number of bytes occupied by the string in @p src.
752 static size_t pull_ascii_base_talloc(TALLOC_CTX *ctx,
767 if (src_len == (size_t)-1) {
768 smb_panic("sec_len == -1 in pull_ascii_base_talloc");
771 if (flags & STR_TERMINATE) {
772 size_t len = strnlen((const char *)src, src_len);
776 /* Ensure we don't use an insane length from the client. */
777 if (src_len >= 1024*1024) {
778 char *msg = talloc_asprintf(ctx,
779 "Bad src length (%u) in "
780 "pull_ascii_base_talloc",
781 (unsigned int)src_len);
786 /* src_len != -1 here. */
788 if (!convert_string_talloc(ctx, CH_DOS, CH_UNIX, src, src_len, &dest,
793 if (dest_len && dest) {
794 /* Did we already process the terminating zero ? */
795 if (dest[dest_len-1] != 0) {
796 size_t size = talloc_get_size(dest);
797 /* Have we got space to append the '\0' ? */
798 if (size <= dest_len) {
800 dest = TALLOC_REALLOC_ARRAY(ctx, dest, char,
804 dest_len = (size_t)-1;
809 dest[dest_len] = '\0';
821 * Copy a string from a char* src to a unicode destination.
823 * @returns the number of bytes occupied by the string in the destination.
825 * @param flags can have:
828 * <dt>STR_TERMINATE <dd>means include the null termination.
829 * <dt>STR_UPPER <dd>means uppercase in the destination.
830 * <dt>STR_NOALIGN <dd>means don't do alignment.
833 * @param dest_len is the maximum length allowed in the
837 size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_len, int flags)
843 if (dest_len == (size_t)-1) {
844 /* No longer allow dest_len of -1. */
845 smb_panic("push_ucs2 - invalid dest_len of -1");
848 if (flags & STR_TERMINATE)
849 src_len = (size_t)-1;
851 src_len = strlen(src);
853 if (ucs2_align(base_ptr, dest, flags)) {
855 dest = (void *)((char *)dest + 1);
861 /* ucs2 is always a multiple of 2 bytes */
864 ret = convert_string(CH_UNIX, CH_UTF16LE, src, src_len, dest, dest_len);
865 if (ret == (size_t)-1) {
866 if ((flags & STR_TERMINATE) &&
876 if (flags & STR_UPPER) {
877 smb_ucs2_t *dest_ucs2 = (smb_ucs2_t *)dest;
880 /* We check for i < (ret / 2) below as the dest string isn't null
881 terminated if STR_TERMINATE isn't set. */
883 for (i = 0; i < (ret / 2) && i < (dest_len / 2) && dest_ucs2[i]; i++) {
884 smb_ucs2_t v = toupper_m(dest_ucs2[i]);
885 if (v != dest_ucs2[i]) {
896 * Copy a string from a unix char* src to a UCS2 destination,
897 * allocating a buffer using talloc().
899 * @param dest always set at least to NULL
900 * @parm converted_size set to the number of bytes occupied by the string in
901 * the destination on success.
903 * @return true if new buffer was correctly allocated, and string was
906 bool push_ucs2_talloc(TALLOC_CTX *ctx, smb_ucs2_t **dest, const char *src,
907 size_t *converted_size)
909 size_t src_len = strlen(src)+1;
912 return convert_string_talloc(ctx, CH_UNIX, CH_UTF16LE, src, src_len,
913 (void **)dest, converted_size);
918 * Copy a string from a unix char* src to a UTF-8 destination, allocating a buffer using talloc
920 * @param dest always set at least to NULL
921 * @parm converted_size set to the number of bytes occupied by the string in
922 * the destination on success.
924 * @return true if new buffer was correctly allocated, and string was
928 bool push_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src,
929 size_t *converted_size)
931 size_t src_len = strlen(src)+1;
934 return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len,
935 (void**)dest, converted_size);
939 Copy a string from a ucs2 source to a unix char* destination.
941 STR_TERMINATE means the string in src is null terminated.
942 STR_NOALIGN means don't try to align.
943 if STR_TERMINATE is set then src_len is ignored if it is -1.
944 src_len is the length of the source area in bytes
945 Return the number of bytes occupied by the string in src.
946 The resulting string in "dest" is always null terminated.
949 size_t pull_ucs2(const void *base_ptr, char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
952 size_t ucs2_align_len = 0;
954 if (dest_len == (size_t)-1) {
955 /* No longer allow dest_len of -1. */
956 smb_panic("pull_ucs2 - invalid dest_len of -1");
960 if (dest && dest_len > 0) {
966 if (ucs2_align(base_ptr, src, flags)) {
967 src = (const void *)((const char *)src + 1);
968 if (src_len != (size_t)-1)
973 if (flags & STR_TERMINATE) {
974 /* src_len -1 is the default for null terminated strings. */
975 if (src_len != (size_t)-1) {
976 size_t len = strnlen_w((const smb_ucs2_t *)src,
984 /* ucs2 is always a multiple of 2 bytes */
985 if (src_len != (size_t)-1)
988 ret = convert_string(CH_UTF16LE, CH_UNIX, src, src_len, dest, dest_len);
989 if (ret == (size_t)-1) {
994 if (src_len == (size_t)-1)
997 if (dest_len && ret) {
998 /* Did we already process the terminating zero ? */
999 if (dest[MIN(ret-1, dest_len-1)] != 0) {
1000 dest[MIN(ret, dest_len-1)] = 0;
1006 return src_len + ucs2_align_len;
1010 Copy a string from a ucs2 source to a unix char* destination.
1011 Talloc version with a base pointer.
1012 Uses malloc if TALLOC_CTX is NULL (this is a bad interface and
1015 STR_TERMINATE means the string in src is null terminated.
1016 STR_NOALIGN means don't try to align.
1017 if STR_TERMINATE is set then src_len is ignored if it is -1.
1018 src_len is the length of the source area in bytes
1019 Return the number of bytes occupied by the string in src.
1020 The resulting string in "dest" is always null terminated.
1023 static size_t pull_ucs2_base_talloc(TALLOC_CTX *ctx,
1024 const void *base_ptr,
1032 size_t ucs2_align_len = 0;
1037 /* Ensure we never use the braindead "malloc" varient. */
1039 smb_panic("NULL talloc CTX in pull_ucs2_base_talloc\n");
1047 if (src_len == (size_t)-1) {
1048 /* no longer used anywhere, but worth checking */
1049 smb_panic("sec_len == -1 in pull_ucs2_base_talloc");
1052 if (ucs2_align(base_ptr, src, flags)) {
1053 src = (const void *)((const char *)src + 1);
1058 if (flags & STR_TERMINATE) {
1059 /* src_len -1 is the default for null terminated strings. */
1060 size_t len = strnlen_w((const smb_ucs2_t *)src,
1062 if (len < src_len/2)
1066 /* Ensure we don't use an insane length from the client. */
1067 if (src_len >= 1024*1024) {
1068 smb_panic("Bad src length in pull_ucs2_base_talloc\n");
1072 /* ucs2 is always a multiple of 2 bytes */
1075 if (!convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, src, src_len,
1076 (void *)&dest, &dest_len)) {
1081 /* Did we already process the terminating zero ? */
1082 if (dest[dest_len-1] != 0) {
1083 size_t size = talloc_get_size(dest);
1084 /* Have we got space to append the '\0' ? */
1085 if (size <= dest_len) {
1087 dest = TALLOC_REALLOC_ARRAY(ctx, dest, char,
1091 dest_len = (size_t)-1;
1096 dest[dest_len] = '\0';
1104 return src_len + ucs2_align_len;
1108 * Copy a string from a UCS2 src to a unix char * destination, allocating a buffer using talloc
1110 * @param dest always set at least to NULL
1111 * @parm converted_size set to the number of bytes occupied by the string in
1112 * the destination on success.
1114 * @return true if new buffer was correctly allocated, and string was
1118 bool pull_ucs2_talloc(TALLOC_CTX *ctx, char **dest, const smb_ucs2_t *src,
1119 size_t *converted_size)
1121 size_t src_len = (strlen_w(src)+1) * sizeof(smb_ucs2_t);
1124 return convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, src, src_len,
1125 (void **)dest, converted_size);
1129 * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer using talloc
1131 * @param dest always set at least to NULL
1132 * @parm converted_size set to the number of bytes occupied by the string in
1133 * the destination on success.
1135 * @return true if new buffer was correctly allocated, and string was
1139 bool pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src,
1140 size_t *converted_size)
1142 size_t src_len = strlen(src)+1;
1145 return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len,
1146 (void **)dest, converted_size);
1151 * Copy a string from a DOS src to a unix char * destination, allocating a buffer using talloc
1153 * @param dest always set at least to NULL
1154 * @parm converted_size set to the number of bytes occupied by the string in
1155 * the destination on success.
1157 * @return true if new buffer was correctly allocated, and string was
1161 bool pull_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src,
1162 size_t *converted_size)
1164 size_t src_len = strlen(src)+1;
1167 return convert_string_talloc(ctx, CH_DOS, CH_UNIX, src, src_len,
1168 (void **)dest, converted_size);
1172 Copy a string from a char* src to a unicode or ascii
1173 dos codepage destination choosing unicode or ascii based on the
1175 Return the number of bytes occupied by the string in the destination.
1177 STR_TERMINATE means include the null termination.
1178 STR_UPPER means uppercase in the destination.
1179 STR_ASCII use ascii even with unicode packet.
1180 STR_NOALIGN means don't do alignment.
1181 dest_len is the maximum length allowed in the destination. If dest_len
1182 is -1 then no maxiumum is used.
1185 size_t push_string_check_fn(void *dest, const char *src,
1186 size_t dest_len, int flags)
1188 if (!(flags & STR_ASCII) && (flags & STR_UNICODE)) {
1189 return push_ucs2(NULL, dest, src, dest_len, flags);
1191 return push_ascii(dest, src, dest_len, flags);
1196 Copy a string from a char* src to a unicode or ascii
1197 dos codepage destination choosing unicode or ascii based on the
1198 flags in the SMB buffer starting at base_ptr.
1199 Return the number of bytes occupied by the string in the destination.
1201 STR_TERMINATE means include the null termination.
1202 STR_UPPER means uppercase in the destination.
1203 STR_ASCII use ascii even with unicode packet.
1204 STR_NOALIGN means don't do alignment.
1205 dest_len is the maximum length allowed in the destination. If dest_len
1206 is -1 then no maxiumum is used.
1209 size_t push_string_base(const char *base, uint16 flags2,
1210 void *dest, const char *src,
1211 size_t dest_len, int flags)
1214 if (!(flags & STR_ASCII) && \
1215 ((flags & STR_UNICODE || \
1216 (flags2 & FLAGS2_UNICODE_STRINGS)))) {
1217 return push_ucs2(base, dest, src, dest_len, flags);
1219 return push_ascii(dest, src, dest_len, flags);
1223 Copy a string from a char* src to a unicode or ascii
1224 dos codepage destination choosing unicode or ascii based on the
1226 Return the number of bytes occupied by the string in the destination.
1228 STR_TERMINATE means include the null termination.
1229 STR_UPPER means uppercase in the destination.
1230 STR_ASCII use ascii even with unicode packet.
1231 STR_NOALIGN means don't do alignment.
1232 dest_len is the maximum length allowed in the destination. If dest_len
1233 is -1 then no maxiumum is used.
1236 ssize_t push_string(void *dest, const char *src, size_t dest_len, int flags)
1240 if (!(flags & STR_ASCII) && \
1241 (flags & STR_UNICODE)) {
1242 ret = push_ucs2(NULL, dest, src, dest_len, flags);
1244 ret = push_ascii(dest, src, dest_len, flags);
1246 if (ret == (size_t)-1) {
1253 Copy a string from a unicode or ascii source (depending on
1254 the packet flags) to a char* destination.
1256 STR_TERMINATE means the string in src is null terminated.
1257 STR_UNICODE means to force as unicode.
1258 STR_ASCII use ascii even with unicode packet.
1259 STR_NOALIGN means don't do alignment.
1260 if STR_TERMINATE is set then src_len is ignored is it is -1
1261 src_len is the length of the source area in bytes.
1262 Return the number of bytes occupied by the string in src.
1263 The resulting string in "dest" is always null terminated.
1266 size_t pull_string_fn(const void *base_ptr,
1274 if ((base_ptr == NULL) && ((flags & (STR_ASCII|STR_UNICODE)) == 0)) {
1275 smb_panic("No base ptr to get flg2 and neither ASCII nor "
1279 if (!(flags & STR_ASCII) && \
1280 ((flags & STR_UNICODE || \
1281 (smb_flags2 & FLAGS2_UNICODE_STRINGS)))) {
1282 return pull_ucs2(base_ptr, dest, src, dest_len, src_len, flags);
1284 return pull_ascii(dest, src, dest_len, src_len, flags);
1288 Copy a string from a unicode or ascii source (depending on
1289 the packet flags) to a char* destination.
1290 Variant that uses talloc.
1292 STR_TERMINATE means the string in src is null terminated.
1293 STR_UNICODE means to force as unicode.
1294 STR_ASCII use ascii even with unicode packet.
1295 STR_NOALIGN means don't do alignment.
1296 if STR_TERMINATE is set then src_len is ignored is it is -1
1297 src_len is the length of the source area in bytes.
1298 Return the number of bytes occupied by the string in src.
1299 The resulting string in "dest" is always null terminated.
1302 size_t pull_string_talloc(TALLOC_CTX *ctx,
1303 const void *base_ptr,
1310 if ((base_ptr == NULL) && ((flags & (STR_ASCII|STR_UNICODE)) == 0)) {
1311 smb_panic("No base ptr to get flg2 and neither ASCII nor "
1315 if (!(flags & STR_ASCII) && \
1316 ((flags & STR_UNICODE || \
1317 (smb_flags2 & FLAGS2_UNICODE_STRINGS)))) {
1318 return pull_ucs2_base_talloc(ctx,
1325 return pull_ascii_base_talloc(ctx,
1333 size_t align_string(const void *base_ptr, const char *p, int flags)
1335 if (!(flags & STR_ASCII) && \
1336 ((flags & STR_UNICODE || \
1337 (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) {
1338 return ucs2_align(base_ptr, p, flags);