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 static 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 * @param converted size is the number of bytes occupied in the destination
85 * @returns false and sets errno on fail, true on success.
87 * Ensure the srclen contains the terminating zero.
91 static bool convert_string_internal(charset_t from, charset_t to,
92 void const *src, size_t srclen,
93 void *dest, size_t destlen, size_t *converted_size)
97 const char* inbuf = (const char*)src;
98 char* outbuf = (char*)dest;
99 smb_iconv_t descriptor;
100 struct smb_iconv_handle *ic;
102 lazy_initialize_conv();
103 ic = get_iconv_handle();
104 descriptor = get_conv_handle(ic, from, to);
106 if (srclen == (size_t)-1) {
107 if (from == CH_UTF16LE || from == CH_UTF16BE) {
108 srclen = (strlen_w((const smb_ucs2_t *)src)+1) * 2;
110 srclen = strlen((const char *)src)+1;
115 if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
123 retval = smb_iconv(descriptor, &inbuf, &i_len, &outbuf, &o_len);
124 if (retval == (size_t)-1) {
127 *converted_size = destlen-o_len;
132 * Convert string from one encoding to another, making error checking etc
133 * Fast path version - handles ASCII first.
135 * @param src pointer to source string (multibyte or singlebyte)
136 * @param srclen length of the source string in bytes, or -1 for nul terminated.
137 * @param dest pointer to destination string (multibyte or singlebyte)
138 * @param destlen maximal length allowed for string - *NEVER* -1.
139 * @param converted size is the number of bytes occupied in the destination
141 * @returns false and sets errno on fail, true on success.
143 * Ensure the srclen contains the terminating zero.
145 * This function has been hand-tuned to provide a fast path.
146 * Don't change unless you really know what you are doing. JRA.
149 bool convert_string_error(charset_t from, charset_t to,
150 void const *src, size_t srclen,
151 void *dest, size_t destlen,
152 size_t *converted_size)
155 * NB. We deliberately don't do a strlen here if srclen == -1.
156 * This is very expensive over millions of calls and is taken
157 * care of in the slow path in convert_string_internal. JRA.
161 SMB_ASSERT(destlen != (size_t)-1);
169 if (from != CH_UTF16LE && from != CH_UTF16BE && to != CH_UTF16LE && to != CH_UTF16BE) {
170 const unsigned char *p = (const unsigned char *)src;
171 unsigned char *q = (unsigned char *)dest;
172 size_t slen = srclen;
173 size_t dlen = destlen;
174 unsigned char lastp = '\0';
177 /* If all characters are ascii, fast path here. */
178 while (slen && dlen) {
179 if ((lastp = *p) <= 0x7f) {
181 if (slen != (size_t)-1) {
189 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
192 bool ret = convert_string_internal(from, to, p, slen, q, dlen, converted_size);
193 *converted_size += retval;
199 *converted_size = retval;
202 /* Even if we fast path we should note if we ran out of room. */
203 if (((slen != (size_t)-1) && slen) ||
204 ((slen == (size_t)-1) && lastp)) {
210 } else if (from == CH_UTF16LE && to != CH_UTF16LE) {
211 const unsigned char *p = (const unsigned char *)src;
212 unsigned char *q = (unsigned char *)dest;
214 size_t slen = srclen;
215 size_t dlen = destlen;
216 unsigned char lastp = '\0';
218 /* If all characters are ascii, fast path here. */
219 while (((slen == (size_t)-1) || (slen >= 2)) && dlen) {
220 if (((lastp = *p) <= 0x7f) && (p[1] == 0)) {
222 if (slen != (size_t)-1) {
231 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
234 bool ret = convert_string_internal(from, to, p, slen, q, dlen, converted_size);
235 *converted_size += retval;
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 bool ret = convert_string_internal(from, to, p, slen, q, dlen, converted_size);
277 *converted_size += retval;
283 *converted_size = retval;
286 /* Even if we fast path we should note if we ran out of room. */
287 if (((slen != (size_t)-1) && slen) ||
288 ((slen == (size_t)-1) && lastp)) {
296 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
299 return convert_string_internal(from, to, src, srclen, dest, destlen, converted_size);
302 bool convert_string(charset_t from, charset_t to,
303 void const *src, size_t srclen,
304 void *dest, size_t destlen,
305 size_t *converted_size)
307 bool ret = convert_string_error(from, to, src, srclen, dest, destlen, converted_size);
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); */
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 (src == NULL || srclen == (size_t)-1) {
389 /* We really should treat this as an error, but
390 there are too many callers that need this to
391 return a NULL terminated string in the correct
393 if (to == CH_UTF16LE|| to == CH_UTF16BE || to == CH_UTF16MUNGED) {
398 ob = talloc_zero_array(ctx, char, destlen);
403 *converted_size = destlen;
408 lazy_initialize_conv();
409 ic = get_iconv_handle();
410 descriptor = get_conv_handle(ic, from, to);
412 if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
413 DEBUG(0,("convert_string_talloc: Conversion not supported.\n"));
420 /* +2 is for ucs2 null termination. */
421 if ((destlen*2)+2 < destlen) {
422 /* wrapped ! abort. */
423 DEBUG(0, ("convert_string_talloc: destlen wrapped !\n"));
428 destlen = destlen * 2;
431 /* +2 is for ucs2 null termination. */
432 ob = (char *)TALLOC_REALLOC(ctx, ob, destlen + 2);
435 DEBUG(0, ("convert_string_talloc: realloc failed!\n"));
443 retval = smb_iconv(descriptor,
446 if(retval == (size_t)-1) {
447 const char *reason="unknown error";
450 reason="Incomplete multibyte sequence";
451 DEBUG(3,("convert_string_talloc: Conversion error: %s(%s)\n",reason,inbuf));
456 reason="Illegal multibyte sequence";
457 DEBUG(3,("convert_string_talloc: Conversion error: %s(%s)\n",reason,inbuf));
460 DEBUG(0,("Conversion error: %s(%s)\n",reason,inbuf));
461 /* smb_panic(reason); */
466 destlen = destlen - o_len;
467 /* Don't shrink unless we're reclaiming a lot of
468 * space. This is in the hot codepath and these
469 * reallocs *cost*. JRA.
472 /* We're shrinking here so we know the +2 is safe from wrap. */
473 ob = (char *)TALLOC_REALLOC(ctx,ob,destlen + 2);
476 if (destlen && !ob) {
477 DEBUG(0, ("convert_string_talloc: out of memory!\n"));
484 /* Must ucs2 null terminate in the extra space we allocated. */
486 ob[destlen+1] = '\0';
488 /* Ensure we can never return a *converted_size of zero. */
490 /* As we're now returning false on a bad smb_iconv call,
491 this should never happen. But be safe anyway. */
492 if (to == CH_UTF16LE|| to == CH_UTF16BE || to == CH_UTF16MUNGED) {
499 *converted_size = destlen;
503 bool unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
509 if (!push_ucs2_talloc(talloc_tos(), &buffer, src, &size)) {
513 if (!strupper_w(buffer) && (dest == src)) {
518 ret = convert_string(CH_UTF16LE, CH_UNIX, buffer, size, dest, destlen, &size);
524 talloc_strdup() a unix string to upper case.
527 char *talloc_strdup_upper(TALLOC_CTX *ctx, const char *s)
529 char *out_buffer = talloc_strdup(ctx,s);
530 const unsigned char *p = (const unsigned char *)s;
531 unsigned char *q = (unsigned char *)out_buffer;
537 /* this is quite a common operation, so we want it to be
538 fast. We optimise for the ascii case, knowing that all our
539 supported multi-byte character sets are ascii-compatible
540 (ie. they match for the first 128 chars) */
545 *q++ = toupper_ascii_fast(*p);
551 size_t converted_size, converted_size2;
552 smb_ucs2_t *ubuf = NULL;
554 /* We're not using the ascii buffer above. */
555 TALLOC_FREE(out_buffer);
557 if (!convert_string_talloc(ctx, CH_UNIX, CH_UTF16LE, s,
558 strlen(s)+1, (void *)&ubuf,
566 if (!convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, ubuf,
567 converted_size, (void *)&out_buffer,
574 /* Don't need the intermediate buffer
583 char *strupper_talloc(TALLOC_CTX *ctx, const char *s) {
584 return talloc_strdup_upper(ctx, s);
588 bool unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
591 smb_ucs2_t *buffer = NULL;
594 if (!convert_string_talloc(talloc_tos(), CH_UNIX, CH_UTF16LE, src, srclen,
595 (void **)(void *)&buffer, &size))
597 smb_panic("failed to create UCS2 buffer");
599 if (!strlower_w(buffer) && (dest == src)) {
603 ret = convert_string(CH_UTF16LE, CH_UNIX, buffer, size, dest, destlen, &size);
609 char *talloc_strdup_lower(TALLOC_CTX *ctx, const char *s)
611 size_t converted_size;
612 smb_ucs2_t *buffer = NULL;
615 if (!push_ucs2_talloc(ctx, &buffer, s, &converted_size)) {
621 if (!pull_ucs2_talloc(ctx, &out_buffer, buffer, &converted_size)) {
631 char *strlower_talloc(TALLOC_CTX *ctx, const char *s) {
632 return talloc_strdup_lower(ctx, s);
637 * Copy a string from a char* unix src to a dos codepage string destination.
639 * @return the number of bytes occupied by the string in the destination.
641 * @param flags can include
643 * <dt>STR_TERMINATE</dt> <dd>means include the null termination</dd>
644 * <dt>STR_UPPER</dt> <dd>means uppercase in the destination</dd>
647 * @param dest_len the maximum length in bytes allowed in the
650 size_t push_ascii(void *dest, const char *src, size_t dest_len, int flags)
652 size_t src_len = strlen(src);
657 /* No longer allow a length of -1. */
658 if (dest_len == (size_t)-1) {
659 smb_panic("push_ascii - dest_len == -1");
662 if (flags & STR_UPPER) {
663 tmpbuf = SMB_STRDUP(src);
665 smb_panic("malloc fail");
671 if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII)) {
675 ret = convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len, &size);
677 (flags & (STR_TERMINATE | STR_TERMINATE_ASCII))
679 ((char *)dest)[0] = '\0';
682 return ret ? size : (size_t)-1;
685 /********************************************************************
686 Push and malloc an ascii string. src and dest null terminated.
687 ********************************************************************/
689 bool push_ascii_talloc(TALLOC_CTX *mem_ctx, char **dest, const char *src, size_t *converted_size)
691 size_t src_len = strlen(src)+1;
694 return convert_string_talloc(mem_ctx, CH_UNIX, CH_DOS, src, src_len,
695 (void **)dest, converted_size);
699 * Copy a string from a dos codepage source to a unix char* destination.
701 * The resulting string in "dest" is always null terminated.
703 * @param flags can have:
705 * <dt>STR_TERMINATE</dt>
706 * <dd>STR_TERMINATE means the string in @p src
707 * is null terminated, and src_len is ignored.</dd>
710 * @param src_len is the length of the source area in bytes.
711 * @returns the number of bytes occupied by the string in @p src.
713 size_t pull_ascii(char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
718 if (dest_len == (size_t)-1) {
719 /* No longer allow dest_len of -1. */
720 smb_panic("pull_ascii - invalid dest_len of -1");
723 if (flags & STR_TERMINATE) {
724 if (src_len == (size_t)-1) {
725 src_len = strlen((const char *)src) + 1;
727 size_t len = strnlen((const char *)src, src_len);
734 ret = convert_string(CH_DOS, CH_UNIX, src, src_len, dest, dest_len, &size);
740 if (dest_len && size) {
741 /* Did we already process the terminating zero ? */
742 if (dest[MIN(size-1, dest_len-1)] != 0) {
743 dest[MIN(size, dest_len-1)] = 0;
753 * Copy a string from a dos codepage source to a unix char* destination.
756 * The resulting string in "dest" is always null terminated.
758 * @param flags can have:
760 * <dt>STR_TERMINATE</dt>
761 * <dd>STR_TERMINATE means the string in @p src
762 * is null terminated, and src_len is ignored.</dd>
765 * @param src_len is the length of the source area in bytes.
766 * @returns the number of bytes occupied by the string in @p src.
769 static size_t pull_ascii_base_talloc(TALLOC_CTX *ctx,
784 if (src_len == (size_t)-1) {
785 smb_panic("sec_len == -1 in pull_ascii_base_talloc");
788 if (flags & STR_TERMINATE) {
789 size_t len = strnlen((const char *)src, src_len);
793 /* Ensure we don't use an insane length from the client. */
794 if (src_len >= 1024*1024) {
795 char *msg = talloc_asprintf(ctx,
796 "Bad src length (%u) in "
797 "pull_ascii_base_talloc",
798 (unsigned int)src_len);
803 /* src_len != -1 here. */
805 if (!convert_string_talloc(ctx, CH_DOS, CH_UNIX, src, src_len, &dest,
810 if (dest_len && dest) {
811 /* Did we already process the terminating zero ? */
812 if (dest[dest_len-1] != 0) {
813 size_t size = talloc_get_size(dest);
814 /* Have we got space to append the '\0' ? */
815 if (size <= dest_len) {
817 dest = TALLOC_REALLOC_ARRAY(ctx, dest, char,
821 dest_len = (size_t)-1;
826 dest[dest_len] = '\0';
838 * Copy a string from a char* src to a unicode destination.
840 * @returns the number of bytes occupied by the string in the destination.
842 * @param flags can have:
845 * <dt>STR_TERMINATE <dd>means include the null termination.
846 * <dt>STR_UPPER <dd>means uppercase in the destination.
847 * <dt>STR_NOALIGN <dd>means don't do alignment.
850 * @param dest_len is the maximum length allowed in the
854 size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_len, int flags)
861 if (dest_len == (size_t)-1) {
862 /* No longer allow dest_len of -1. */
863 smb_panic("push_ucs2 - invalid dest_len of -1");
866 if (flags & STR_TERMINATE)
867 src_len = (size_t)-1;
869 src_len = strlen(src);
871 if (ucs2_align(base_ptr, dest, flags)) {
873 dest = (void *)((char *)dest + 1);
879 /* ucs2 is always a multiple of 2 bytes */
882 ret = convert_string(CH_UNIX, CH_UTF16LE, src, src_len, dest, dest_len, &size);
884 if ((flags & STR_TERMINATE) &&
894 if (flags & STR_UPPER) {
895 smb_ucs2_t *dest_ucs2 = (smb_ucs2_t *)dest;
898 /* We check for i < (ret / 2) below as the dest string isn't null
899 terminated if STR_TERMINATE isn't set. */
901 for (i = 0; i < (ret / 2) && i < (dest_len / 2) && dest_ucs2[i]; i++) {
902 smb_ucs2_t v = toupper_m(dest_ucs2[i]);
903 if (v != dest_ucs2[i]) {
914 * Copy a string from a unix char* src to a UCS2 destination,
915 * allocating a buffer using talloc().
917 * @param dest always set at least to NULL
918 * @parm converted_size set to the number of bytes occupied by the string in
919 * the destination on success.
921 * @return true if new buffer was correctly allocated, and string was
924 bool push_ucs2_talloc(TALLOC_CTX *ctx, smb_ucs2_t **dest, const char *src,
925 size_t *converted_size)
927 size_t src_len = strlen(src)+1;
930 return convert_string_talloc(ctx, CH_UNIX, CH_UTF16LE, src, src_len,
931 (void **)dest, converted_size);
936 * Copy a string from a unix char* src to a UTF-8 destination, allocating a buffer using talloc
938 * @param dest always set at least to NULL
939 * @parm converted_size set to the number of bytes occupied by the string in
940 * the destination on success.
942 * @return true if new buffer was correctly allocated, and string was
946 bool push_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src,
947 size_t *converted_size)
949 size_t src_len = strlen(src)+1;
952 return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len,
953 (void**)dest, converted_size);
957 Copy a string from a ucs2 source to a unix char* destination.
959 STR_TERMINATE means the string in src is null terminated.
960 STR_NOALIGN means don't try to align.
961 if STR_TERMINATE is set then src_len is ignored if it is -1.
962 src_len is the length of the source area in bytes
963 Return the number of bytes occupied by the string in src.
964 The resulting string in "dest" is always null terminated.
967 static size_t pull_ucs2(const void *base_ptr, char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
970 size_t ucs2_align_len = 0;
973 if (dest_len == (size_t)-1) {
974 /* No longer allow dest_len of -1. */
975 smb_panic("pull_ucs2 - invalid dest_len of -1");
979 if (dest && dest_len > 0) {
985 if (ucs2_align(base_ptr, src, flags)) {
986 src = (const void *)((const char *)src + 1);
987 if (src_len != (size_t)-1)
992 if (flags & STR_TERMINATE) {
993 /* src_len -1 is the default for null terminated strings. */
994 if (src_len != (size_t)-1) {
995 size_t len = strnlen_w((const smb_ucs2_t *)src,
1003 /* ucs2 is always a multiple of 2 bytes */
1004 if (src_len != (size_t)-1)
1007 ret = convert_string(CH_UTF16LE, CH_UNIX, src, src_len, dest, dest_len, &size);
1013 if (src_len == (size_t)-1)
1016 if (dest_len && size) {
1017 /* Did we already process the terminating zero ? */
1018 if (dest[MIN(size-1, dest_len-1)] != 0) {
1019 dest[MIN(size, dest_len-1)] = 0;
1025 return src_len + ucs2_align_len;
1029 Copy a string from a ucs2 source to a unix char* destination.
1030 Talloc version with a base pointer.
1031 Uses malloc if TALLOC_CTX is NULL (this is a bad interface and
1034 STR_TERMINATE means the string in src is null terminated.
1035 STR_NOALIGN means don't try to align.
1036 if STR_TERMINATE is set then src_len is ignored if it is -1.
1037 src_len is the length of the source area in bytes
1038 Return the number of bytes occupied by the string in src.
1039 The resulting string in "dest" is always null terminated.
1042 static size_t pull_ucs2_base_talloc(TALLOC_CTX *ctx,
1043 const void *base_ptr,
1051 size_t ucs2_align_len = 0;
1056 /* Ensure we never use the braindead "malloc" varient. */
1058 smb_panic("NULL talloc CTX in pull_ucs2_base_talloc\n");
1066 if (src_len == (size_t)-1) {
1067 /* no longer used anywhere, but worth checking */
1068 smb_panic("sec_len == -1 in pull_ucs2_base_talloc");
1071 if (ucs2_align(base_ptr, src, flags)) {
1072 src = (const void *)((const char *)src + 1);
1077 if (flags & STR_TERMINATE) {
1078 /* src_len -1 is the default for null terminated strings. */
1079 size_t len = strnlen_w((const smb_ucs2_t *)src,
1081 if (len < src_len/2)
1085 /* Ensure we don't use an insane length from the client. */
1086 if (src_len >= 1024*1024) {
1087 smb_panic("Bad src length in pull_ucs2_base_talloc\n");
1091 /* ucs2 is always a multiple of 2 bytes */
1094 if (!convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, src, src_len,
1095 (void *)&dest, &dest_len)) {
1100 /* Did we already process the terminating zero ? */
1101 if (dest[dest_len-1] != 0) {
1102 size_t size = talloc_get_size(dest);
1103 /* Have we got space to append the '\0' ? */
1104 if (size <= dest_len) {
1106 dest = TALLOC_REALLOC_ARRAY(ctx, dest, char,
1110 dest_len = (size_t)-1;
1115 dest[dest_len] = '\0';
1123 return src_len + ucs2_align_len;
1127 * Copy a string from a UCS2 src to a unix char * destination, allocating a buffer using talloc
1129 * @param dest always set at least to NULL
1130 * @parm converted_size set to the number of bytes occupied by the string in
1131 * the destination on success.
1133 * @return true if new buffer was correctly allocated, and string was
1137 bool pull_ucs2_talloc(TALLOC_CTX *ctx, char **dest, const smb_ucs2_t *src,
1138 size_t *converted_size)
1140 size_t src_len = (strlen_w(src)+1) * sizeof(smb_ucs2_t);
1143 return convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, src, src_len,
1144 (void **)dest, converted_size);
1148 * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer using talloc
1150 * @param dest always set at least to NULL
1151 * @parm converted_size set to the number of bytes occupied by the string in
1152 * the destination on success.
1154 * @return true if new buffer was correctly allocated, and string was
1158 bool pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src,
1159 size_t *converted_size)
1161 size_t src_len = strlen(src)+1;
1164 return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len,
1165 (void **)dest, converted_size);
1170 * Copy a string from a DOS src to a unix char * destination, allocating a buffer using talloc
1172 * @param dest always set at least to NULL
1173 * @parm converted_size set to the number of bytes occupied by the string in
1174 * the destination on success.
1176 * @return true if new buffer was correctly allocated, and string was
1180 bool pull_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src,
1181 size_t *converted_size)
1183 size_t src_len = strlen(src)+1;
1186 return convert_string_talloc(ctx, CH_DOS, CH_UNIX, src, src_len,
1187 (void **)dest, converted_size);
1191 Copy a string from a char* src to a unicode or ascii
1192 dos codepage destination choosing unicode or ascii based on the
1194 Return the number of bytes occupied by the string in the destination.
1196 STR_TERMINATE means include the null termination.
1197 STR_UPPER means uppercase in the destination.
1198 STR_ASCII use ascii even with unicode packet.
1199 STR_NOALIGN means don't do alignment.
1200 dest_len is the maximum length allowed in the destination. If dest_len
1201 is -1 then no maxiumum is used.
1204 size_t push_string_check_fn(void *dest, const char *src,
1205 size_t dest_len, int flags)
1207 if (!(flags & STR_ASCII) && (flags & STR_UNICODE)) {
1208 return push_ucs2(NULL, dest, src, dest_len, flags);
1210 return push_ascii(dest, src, dest_len, flags);
1215 Copy a string from a char* src to a unicode or ascii
1216 dos codepage destination choosing unicode or ascii based on the
1217 flags in the SMB buffer starting at base_ptr.
1218 Return the number of bytes occupied by the string in the destination.
1220 STR_TERMINATE means include the null termination.
1221 STR_UPPER means uppercase in the destination.
1222 STR_ASCII use ascii even with unicode packet.
1223 STR_NOALIGN means don't do alignment.
1224 dest_len is the maximum length allowed in the destination. If dest_len
1225 is -1 then no maxiumum is used.
1228 size_t push_string_base(const char *base, uint16 flags2,
1229 void *dest, const char *src,
1230 size_t dest_len, int flags)
1233 if (!(flags & STR_ASCII) && \
1234 ((flags & STR_UNICODE || \
1235 (flags2 & FLAGS2_UNICODE_STRINGS)))) {
1236 return push_ucs2(base, dest, src, dest_len, flags);
1238 return push_ascii(dest, src, dest_len, flags);
1242 Copy a string from a char* src to a unicode or ascii
1243 dos codepage destination choosing unicode or ascii based on the
1245 Return the number of bytes occupied by the string in the destination.
1247 STR_TERMINATE means include the null termination.
1248 STR_UPPER means uppercase in the destination.
1249 STR_ASCII use ascii even with unicode packet.
1250 STR_NOALIGN means don't do alignment.
1251 dest_len is the maximum length allowed in the destination. If dest_len
1252 is -1 then no maxiumum is used.
1255 ssize_t push_string(void *dest, const char *src, size_t dest_len, int flags)
1259 if (!(flags & STR_ASCII) && \
1260 (flags & STR_UNICODE)) {
1261 ret = push_ucs2(NULL, dest, src, dest_len, flags);
1263 ret = push_ascii(dest, src, dest_len, flags);
1265 if (ret == (size_t)-1) {
1272 Copy a string from a unicode or ascii source (depending on
1273 the packet flags) to a char* destination.
1275 STR_TERMINATE means the string in src is null terminated.
1276 STR_UNICODE means to force as unicode.
1277 STR_ASCII use ascii even with unicode packet.
1278 STR_NOALIGN means don't do alignment.
1279 if STR_TERMINATE is set then src_len is ignored is it is -1
1280 src_len is the length of the source area in bytes.
1281 Return the number of bytes occupied by the string in src.
1282 The resulting string in "dest" is always null terminated.
1285 size_t pull_string_fn(const void *base_ptr,
1293 if ((base_ptr == NULL) && ((flags & (STR_ASCII|STR_UNICODE)) == 0)) {
1294 smb_panic("No base ptr to get flg2 and neither ASCII nor "
1298 if (!(flags & STR_ASCII) && \
1299 ((flags & STR_UNICODE || \
1300 (smb_flags2 & FLAGS2_UNICODE_STRINGS)))) {
1301 return pull_ucs2(base_ptr, dest, src, dest_len, src_len, flags);
1303 return pull_ascii(dest, src, dest_len, src_len, flags);
1307 Copy a string from a unicode or ascii source (depending on
1308 the packet flags) to a char* destination.
1309 Variant that uses talloc.
1311 STR_TERMINATE means the string in src is null terminated.
1312 STR_UNICODE means to force as unicode.
1313 STR_ASCII use ascii even with unicode packet.
1314 STR_NOALIGN means don't do alignment.
1315 if STR_TERMINATE is set then src_len is ignored is it is -1
1316 src_len is the length of the source area in bytes.
1317 Return the number of bytes occupied by the string in src.
1318 The resulting string in "dest" is always null terminated.
1321 size_t pull_string_talloc(TALLOC_CTX *ctx,
1322 const void *base_ptr,
1329 if ((base_ptr == NULL) && ((flags & (STR_ASCII|STR_UNICODE)) == 0)) {
1330 smb_panic("No base ptr to get flg2 and neither ASCII nor "
1334 if (!(flags & STR_ASCII) && \
1335 ((flags & STR_UNICODE || \
1336 (smb_flags2 & FLAGS2_UNICODE_STRINGS)))) {
1337 return pull_ucs2_base_talloc(ctx,
1344 return pull_ascii_base_talloc(ctx,
1352 size_t align_string(const void *base_ptr, const char *p, int flags)
1354 if (!(flags & STR_ASCII) && \
1355 ((flags & STR_UNICODE || \
1356 (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) {
1357 return ucs2_align(base_ptr, p, flags);
1362 /*******************************************************************
1363 Write a string in (little-endian) unicode format. src is in
1364 the current DOS codepage. len is the length in bytes of the
1365 string pointed to by dst.
1367 if null_terminate is True then null terminate the packet (adds 2 bytes)
1369 the return value is the length in bytes consumed by the string, including the
1370 null termination if applied
1371 ********************************************************************/
1373 size_t dos_PutUniCode(char *dst,const char *src, size_t len, bool null_terminate)
1375 int flags = null_terminate ? STR_UNICODE|STR_NOALIGN|STR_TERMINATE
1376 : STR_UNICODE|STR_NOALIGN;
1377 return push_ucs2(NULL, dst, src, len, flags);
1381 /* Converts a string from internal samba format to unicode
1384 int rpcstr_push(void *dest, const char *src, size_t dest_len, int flags)
1386 return push_ucs2(NULL, dest, src, dest_len, flags|STR_UNICODE|STR_NOALIGN);
1389 /* Converts a string from internal samba format to unicode. Always terminates.
1390 * Actually just a wrapper round push_ucs2_talloc().
1393 int rpcstr_push_talloc(TALLOC_CTX *ctx, smb_ucs2_t **dest, const char *src)
1396 if (push_ucs2_talloc(ctx, dest, src, &size))