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 size_t convert_string(charset_t from, charset_t to,
303 void const *src, size_t srclen,
304 void *dest, size_t destlen)
306 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); */
347 return ret ? converted_size : (size_t)-1;
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 size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
508 if (!push_ucs2_talloc(talloc_tos(), &buffer, src, &size)) {
512 if (!strupper_w(buffer) && (dest == src)) {
517 size = convert_string(CH_UTF16LE, CH_UNIX, buffer, size, dest, destlen);
523 talloc_strdup() a unix string to upper case.
526 char *talloc_strdup_upper(TALLOC_CTX *ctx, const char *s)
528 char *out_buffer = talloc_strdup(ctx,s);
529 const unsigned char *p = (const unsigned char *)s;
530 unsigned char *q = (unsigned char *)out_buffer;
536 /* this is quite a common operation, so we want it to be
537 fast. We optimise for the ascii case, knowing that all our
538 supported multi-byte character sets are ascii-compatible
539 (ie. they match for the first 128 chars) */
544 *q++ = toupper_ascii_fast(*p);
550 size_t converted_size, converted_size2;
551 smb_ucs2_t *ubuf = NULL;
553 /* We're not using the ascii buffer above. */
554 TALLOC_FREE(out_buffer);
556 if (!convert_string_talloc(ctx, CH_UNIX, CH_UTF16LE, s,
557 strlen(s)+1, (void *)&ubuf,
565 if (!convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, ubuf,
566 converted_size, (void *)&out_buffer,
573 /* Don't need the intermediate buffer
582 char *strupper_talloc(TALLOC_CTX *ctx, const char *s) {
583 return talloc_strdup_upper(ctx, s);
587 size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
590 smb_ucs2_t *buffer = NULL;
592 if (!convert_string_talloc(talloc_tos(), CH_UNIX, CH_UTF16LE, src, srclen,
593 (void **)(void *)&buffer, &size))
595 smb_panic("failed to create UCS2 buffer");
597 if (!strlower_w(buffer) && (dest == src)) {
601 size = convert_string(CH_UTF16LE, CH_UNIX, buffer, size, dest, destlen);
607 char *talloc_strdup_lower(TALLOC_CTX *ctx, const char *s)
609 size_t converted_size;
610 smb_ucs2_t *buffer = NULL;
613 if (!push_ucs2_talloc(ctx, &buffer, s, &converted_size)) {
619 if (!pull_ucs2_talloc(ctx, &out_buffer, buffer, &converted_size)) {
629 char *strlower_talloc(TALLOC_CTX *ctx, const char *s) {
630 return talloc_strdup_lower(ctx, s);
633 size_t ucs2_align(const void *base_ptr, const void *p, int flags)
635 if (flags & (STR_NOALIGN|STR_ASCII))
637 return PTR_DIFF(p, base_ptr) & 1;
642 * Copy a string from a char* unix src to a dos codepage string destination.
644 * @return the number of bytes occupied by the string in the destination.
646 * @param flags can include
648 * <dt>STR_TERMINATE</dt> <dd>means include the null termination</dd>
649 * <dt>STR_UPPER</dt> <dd>means uppercase in the destination</dd>
652 * @param dest_len the maximum length in bytes allowed in the
655 size_t push_ascii(void *dest, const char *src, size_t dest_len, int flags)
657 size_t src_len = strlen(src);
661 /* No longer allow a length of -1. */
662 if (dest_len == (size_t)-1) {
663 smb_panic("push_ascii - dest_len == -1");
666 if (flags & STR_UPPER) {
667 tmpbuf = SMB_STRDUP(src);
669 smb_panic("malloc fail");
675 if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII)) {
679 ret = convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len);
680 if (ret == (size_t)-1 &&
681 (flags & (STR_TERMINATE | STR_TERMINATE_ASCII))
683 ((char *)dest)[0] = '\0';
689 /********************************************************************
690 Push and malloc an ascii string. src and dest null terminated.
691 ********************************************************************/
693 bool push_ascii_talloc(TALLOC_CTX *mem_ctx, char **dest, const char *src, size_t *converted_size)
695 size_t src_len = strlen(src)+1;
698 return convert_string_talloc(mem_ctx, CH_UNIX, CH_DOS, src, src_len,
699 (void **)dest, converted_size);
703 * Copy a string from a dos codepage source to a unix char* destination.
705 * The resulting string in "dest" is always null terminated.
707 * @param flags can have:
709 * <dt>STR_TERMINATE</dt>
710 * <dd>STR_TERMINATE means the string in @p src
711 * is null terminated, and src_len is ignored.</dd>
714 * @param src_len is the length of the source area in bytes.
715 * @returns the number of bytes occupied by the string in @p src.
717 size_t pull_ascii(char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
721 if (dest_len == (size_t)-1) {
722 /* No longer allow dest_len of -1. */
723 smb_panic("pull_ascii - invalid dest_len of -1");
726 if (flags & STR_TERMINATE) {
727 if (src_len == (size_t)-1) {
728 src_len = strlen((const char *)src) + 1;
730 size_t len = strnlen((const char *)src, src_len);
737 ret = convert_string(CH_DOS, CH_UNIX, src, src_len, dest, dest_len);
738 if (ret == (size_t)-1) {
743 if (dest_len && ret) {
744 /* Did we already process the terminating zero ? */
745 if (dest[MIN(ret-1, dest_len-1)] != 0) {
746 dest[MIN(ret, dest_len-1)] = 0;
756 * Copy a string from a dos codepage source to a unix char* destination.
759 * The resulting string in "dest" is always null terminated.
761 * @param flags can have:
763 * <dt>STR_TERMINATE</dt>
764 * <dd>STR_TERMINATE means the string in @p src
765 * is null terminated, and src_len is ignored.</dd>
768 * @param src_len is the length of the source area in bytes.
769 * @returns the number of bytes occupied by the string in @p src.
772 static size_t pull_ascii_base_talloc(TALLOC_CTX *ctx,
787 if (src_len == (size_t)-1) {
788 smb_panic("sec_len == -1 in pull_ascii_base_talloc");
791 if (flags & STR_TERMINATE) {
792 size_t len = strnlen((const char *)src, src_len);
796 /* Ensure we don't use an insane length from the client. */
797 if (src_len >= 1024*1024) {
798 char *msg = talloc_asprintf(ctx,
799 "Bad src length (%u) in "
800 "pull_ascii_base_talloc",
801 (unsigned int)src_len);
806 /* src_len != -1 here. */
808 if (!convert_string_talloc(ctx, CH_DOS, CH_UNIX, src, src_len, &dest,
813 if (dest_len && dest) {
814 /* Did we already process the terminating zero ? */
815 if (dest[dest_len-1] != 0) {
816 size_t size = talloc_get_size(dest);
817 /* Have we got space to append the '\0' ? */
818 if (size <= dest_len) {
820 dest = TALLOC_REALLOC_ARRAY(ctx, dest, char,
824 dest_len = (size_t)-1;
829 dest[dest_len] = '\0';
841 * Copy a string from a char* src to a unicode destination.
843 * @returns the number of bytes occupied by the string in the destination.
845 * @param flags can have:
848 * <dt>STR_TERMINATE <dd>means include the null termination.
849 * <dt>STR_UPPER <dd>means uppercase in the destination.
850 * <dt>STR_NOALIGN <dd>means don't do alignment.
853 * @param dest_len is the maximum length allowed in the
857 size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_len, int flags)
863 if (dest_len == (size_t)-1) {
864 /* No longer allow dest_len of -1. */
865 smb_panic("push_ucs2 - invalid dest_len of -1");
868 if (flags & STR_TERMINATE)
869 src_len = (size_t)-1;
871 src_len = strlen(src);
873 if (ucs2_align(base_ptr, dest, flags)) {
875 dest = (void *)((char *)dest + 1);
881 /* ucs2 is always a multiple of 2 bytes */
884 ret = convert_string(CH_UNIX, CH_UTF16LE, src, src_len, dest, dest_len);
885 if (ret == (size_t)-1) {
886 if ((flags & STR_TERMINATE) &&
896 if (flags & STR_UPPER) {
897 smb_ucs2_t *dest_ucs2 = (smb_ucs2_t *)dest;
900 /* We check for i < (ret / 2) below as the dest string isn't null
901 terminated if STR_TERMINATE isn't set. */
903 for (i = 0; i < (ret / 2) && i < (dest_len / 2) && dest_ucs2[i]; i++) {
904 smb_ucs2_t v = toupper_m(dest_ucs2[i]);
905 if (v != dest_ucs2[i]) {
916 * Copy a string from a unix char* src to a UCS2 destination,
917 * allocating a buffer using talloc().
919 * @param dest always set at least to NULL
920 * @parm converted_size set to the number of bytes occupied by the string in
921 * the destination on success.
923 * @return true if new buffer was correctly allocated, and string was
926 bool push_ucs2_talloc(TALLOC_CTX *ctx, smb_ucs2_t **dest, const char *src,
927 size_t *converted_size)
929 size_t src_len = strlen(src)+1;
932 return convert_string_talloc(ctx, CH_UNIX, CH_UTF16LE, src, src_len,
933 (void **)dest, converted_size);
938 * Copy a string from a unix char* src to a UTF-8 destination, allocating a buffer using talloc
940 * @param dest always set at least to NULL
941 * @parm converted_size set to the number of bytes occupied by the string in
942 * the destination on success.
944 * @return true if new buffer was correctly allocated, and string was
948 bool push_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src,
949 size_t *converted_size)
951 size_t src_len = strlen(src)+1;
954 return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len,
955 (void**)dest, converted_size);
959 Copy a string from a ucs2 source to a unix char* destination.
961 STR_TERMINATE means the string in src is null terminated.
962 STR_NOALIGN means don't try to align.
963 if STR_TERMINATE is set then src_len is ignored if it is -1.
964 src_len is the length of the source area in bytes
965 Return the number of bytes occupied by the string in src.
966 The resulting string in "dest" is always null terminated.
969 size_t pull_ucs2(const void *base_ptr, char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
972 size_t ucs2_align_len = 0;
974 if (dest_len == (size_t)-1) {
975 /* No longer allow dest_len of -1. */
976 smb_panic("pull_ucs2 - invalid dest_len of -1");
980 if (dest && dest_len > 0) {
986 if (ucs2_align(base_ptr, src, flags)) {
987 src = (const void *)((const char *)src + 1);
988 if (src_len != (size_t)-1)
993 if (flags & STR_TERMINATE) {
994 /* src_len -1 is the default for null terminated strings. */
995 if (src_len != (size_t)-1) {
996 size_t len = strnlen_w((const smb_ucs2_t *)src,
1004 /* ucs2 is always a multiple of 2 bytes */
1005 if (src_len != (size_t)-1)
1008 ret = convert_string(CH_UTF16LE, CH_UNIX, src, src_len, dest, dest_len);
1009 if (ret == (size_t)-1) {
1014 if (src_len == (size_t)-1)
1017 if (dest_len && ret) {
1018 /* Did we already process the terminating zero ? */
1019 if (dest[MIN(ret-1, dest_len-1)] != 0) {
1020 dest[MIN(ret, dest_len-1)] = 0;
1026 return src_len + ucs2_align_len;
1030 Copy a string from a ucs2 source to a unix char* destination.
1031 Talloc version with a base pointer.
1032 Uses malloc if TALLOC_CTX is NULL (this is a bad interface and
1035 STR_TERMINATE means the string in src is null terminated.
1036 STR_NOALIGN means don't try to align.
1037 if STR_TERMINATE is set then src_len is ignored if it is -1.
1038 src_len is the length of the source area in bytes
1039 Return the number of bytes occupied by the string in src.
1040 The resulting string in "dest" is always null terminated.
1043 static size_t pull_ucs2_base_talloc(TALLOC_CTX *ctx,
1044 const void *base_ptr,
1052 size_t ucs2_align_len = 0;
1057 /* Ensure we never use the braindead "malloc" varient. */
1059 smb_panic("NULL talloc CTX in pull_ucs2_base_talloc\n");
1067 if (src_len == (size_t)-1) {
1068 /* no longer used anywhere, but worth checking */
1069 smb_panic("sec_len == -1 in pull_ucs2_base_talloc");
1072 if (ucs2_align(base_ptr, src, flags)) {
1073 src = (const void *)((const char *)src + 1);
1078 if (flags & STR_TERMINATE) {
1079 /* src_len -1 is the default for null terminated strings. */
1080 size_t len = strnlen_w((const smb_ucs2_t *)src,
1082 if (len < src_len/2)
1086 /* Ensure we don't use an insane length from the client. */
1087 if (src_len >= 1024*1024) {
1088 smb_panic("Bad src length in pull_ucs2_base_talloc\n");
1092 /* ucs2 is always a multiple of 2 bytes */
1095 if (!convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, src, src_len,
1096 (void *)&dest, &dest_len)) {
1101 /* Did we already process the terminating zero ? */
1102 if (dest[dest_len-1] != 0) {
1103 size_t size = talloc_get_size(dest);
1104 /* Have we got space to append the '\0' ? */
1105 if (size <= dest_len) {
1107 dest = TALLOC_REALLOC_ARRAY(ctx, dest, char,
1111 dest_len = (size_t)-1;
1116 dest[dest_len] = '\0';
1124 return src_len + ucs2_align_len;
1128 * Copy a string from a UCS2 src to a unix char * destination, allocating a buffer using talloc
1130 * @param dest always set at least to NULL
1131 * @parm converted_size set to the number of bytes occupied by the string in
1132 * the destination on success.
1134 * @return true if new buffer was correctly allocated, and string was
1138 bool pull_ucs2_talloc(TALLOC_CTX *ctx, char **dest, const smb_ucs2_t *src,
1139 size_t *converted_size)
1141 size_t src_len = (strlen_w(src)+1) * sizeof(smb_ucs2_t);
1144 return convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, src, src_len,
1145 (void **)dest, converted_size);
1149 * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer using talloc
1151 * @param dest always set at least to NULL
1152 * @parm converted_size set to the number of bytes occupied by the string in
1153 * the destination on success.
1155 * @return true if new buffer was correctly allocated, and string was
1159 bool pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src,
1160 size_t *converted_size)
1162 size_t src_len = strlen(src)+1;
1165 return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len,
1166 (void **)dest, converted_size);
1171 * Copy a string from a DOS src to a unix char * destination, allocating a buffer using talloc
1173 * @param dest always set at least to NULL
1174 * @parm converted_size set to the number of bytes occupied by the string in
1175 * the destination on success.
1177 * @return true if new buffer was correctly allocated, and string was
1181 bool pull_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src,
1182 size_t *converted_size)
1184 size_t src_len = strlen(src)+1;
1187 return convert_string_talloc(ctx, CH_DOS, CH_UNIX, src, src_len,
1188 (void **)dest, converted_size);
1192 Copy a string from a char* src to a unicode or ascii
1193 dos codepage destination choosing unicode or ascii based on the
1195 Return the number of bytes occupied by the string in the destination.
1197 STR_TERMINATE means include the null termination.
1198 STR_UPPER means uppercase in the destination.
1199 STR_ASCII use ascii even with unicode packet.
1200 STR_NOALIGN means don't do alignment.
1201 dest_len is the maximum length allowed in the destination. If dest_len
1202 is -1 then no maxiumum is used.
1205 size_t push_string_check_fn(void *dest, const char *src,
1206 size_t dest_len, int flags)
1208 if (!(flags & STR_ASCII) && (flags & STR_UNICODE)) {
1209 return push_ucs2(NULL, dest, src, dest_len, flags);
1211 return push_ascii(dest, src, dest_len, flags);
1216 Copy a string from a char* src to a unicode or ascii
1217 dos codepage destination choosing unicode or ascii based on the
1218 flags in the SMB buffer starting at base_ptr.
1219 Return the number of bytes occupied by the string in the destination.
1221 STR_TERMINATE means include the null termination.
1222 STR_UPPER means uppercase in the destination.
1223 STR_ASCII use ascii even with unicode packet.
1224 STR_NOALIGN means don't do alignment.
1225 dest_len is the maximum length allowed in the destination. If dest_len
1226 is -1 then no maxiumum is used.
1229 size_t push_string_base(const char *base, uint16 flags2,
1230 void *dest, const char *src,
1231 size_t dest_len, int flags)
1234 if (!(flags & STR_ASCII) && \
1235 ((flags & STR_UNICODE || \
1236 (flags2 & FLAGS2_UNICODE_STRINGS)))) {
1237 return push_ucs2(base, dest, src, dest_len, flags);
1239 return push_ascii(dest, src, dest_len, flags);
1243 Copy a string from a char* src to a unicode or ascii
1244 dos codepage destination choosing unicode or ascii based on the
1246 Return the number of bytes occupied by the string in the destination.
1248 STR_TERMINATE means include the null termination.
1249 STR_UPPER means uppercase in the destination.
1250 STR_ASCII use ascii even with unicode packet.
1251 STR_NOALIGN means don't do alignment.
1252 dest_len is the maximum length allowed in the destination. If dest_len
1253 is -1 then no maxiumum is used.
1256 ssize_t push_string(void *dest, const char *src, size_t dest_len, int flags)
1260 if (!(flags & STR_ASCII) && \
1261 (flags & STR_UNICODE)) {
1262 ret = push_ucs2(NULL, dest, src, dest_len, flags);
1264 ret = push_ascii(dest, src, dest_len, flags);
1266 if (ret == (size_t)-1) {
1273 Copy a string from a unicode or ascii source (depending on
1274 the packet flags) to a char* destination.
1276 STR_TERMINATE means the string in src is null terminated.
1277 STR_UNICODE means to force as unicode.
1278 STR_ASCII use ascii even with unicode packet.
1279 STR_NOALIGN means don't do alignment.
1280 if STR_TERMINATE is set then src_len is ignored is it is -1
1281 src_len is the length of the source area in bytes.
1282 Return the number of bytes occupied by the string in src.
1283 The resulting string in "dest" is always null terminated.
1286 size_t pull_string_fn(const void *base_ptr,
1294 if ((base_ptr == NULL) && ((flags & (STR_ASCII|STR_UNICODE)) == 0)) {
1295 smb_panic("No base ptr to get flg2 and neither ASCII nor "
1299 if (!(flags & STR_ASCII) && \
1300 ((flags & STR_UNICODE || \
1301 (smb_flags2 & FLAGS2_UNICODE_STRINGS)))) {
1302 return pull_ucs2(base_ptr, dest, src, dest_len, src_len, flags);
1304 return pull_ascii(dest, src, dest_len, src_len, flags);
1308 Copy a string from a unicode or ascii source (depending on
1309 the packet flags) to a char* destination.
1310 Variant that uses talloc.
1312 STR_TERMINATE means the string in src is null terminated.
1313 STR_UNICODE means to force as unicode.
1314 STR_ASCII use ascii even with unicode packet.
1315 STR_NOALIGN means don't do alignment.
1316 if STR_TERMINATE is set then src_len is ignored is it is -1
1317 src_len is the length of the source area in bytes.
1318 Return the number of bytes occupied by the string in src.
1319 The resulting string in "dest" is always null terminated.
1322 size_t pull_string_talloc(TALLOC_CTX *ctx,
1323 const void *base_ptr,
1330 if ((base_ptr == NULL) && ((flags & (STR_ASCII|STR_UNICODE)) == 0)) {
1331 smb_panic("No base ptr to get flg2 and neither ASCII nor "
1335 if (!(flags & STR_ASCII) && \
1336 ((flags & STR_UNICODE || \
1337 (smb_flags2 & FLAGS2_UNICODE_STRINGS)))) {
1338 return pull_ucs2_base_talloc(ctx,
1345 return pull_ascii_base_talloc(ctx,
1353 size_t align_string(const void *base_ptr, const char *p, int flags)
1355 if (!(flags & STR_ASCII) && \
1356 ((flags & STR_UNICODE || \
1357 (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) {
1358 return ucs2_align(base_ptr, p, flags);