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
);
635 size_t ucs2_align(const void *base_ptr
, const void *p
, int flags
)
637 if (flags
& (STR_NOALIGN
|STR_ASCII
))
639 return PTR_DIFF(p
, base_ptr
) & 1;
644 * Copy a string from a char* unix src to a dos codepage string destination.
646 * @return the number of bytes occupied by the string in the destination.
648 * @param flags can include
650 * <dt>STR_TERMINATE</dt> <dd>means include the null termination</dd>
651 * <dt>STR_UPPER</dt> <dd>means uppercase in the destination</dd>
654 * @param dest_len the maximum length in bytes allowed in the
657 size_t push_ascii(void *dest
, const char *src
, size_t dest_len
, int flags
)
659 size_t src_len
= strlen(src
);
664 /* No longer allow a length of -1. */
665 if (dest_len
== (size_t)-1) {
666 smb_panic("push_ascii - dest_len == -1");
669 if (flags
& STR_UPPER
) {
670 tmpbuf
= SMB_STRDUP(src
);
672 smb_panic("malloc fail");
678 if (flags
& (STR_TERMINATE
| STR_TERMINATE_ASCII
)) {
682 ret
= convert_string(CH_UNIX
, CH_DOS
, src
, src_len
, dest
, dest_len
, &size
);
684 (flags
& (STR_TERMINATE
| STR_TERMINATE_ASCII
))
686 ((char *)dest
)[0] = '\0';
689 return ret
? size
: (size_t)-1;
692 /********************************************************************
693 Push and malloc an ascii string. src and dest null terminated.
694 ********************************************************************/
696 bool push_ascii_talloc(TALLOC_CTX
*mem_ctx
, char **dest
, const char *src
, size_t *converted_size
)
698 size_t src_len
= strlen(src
)+1;
701 return convert_string_talloc(mem_ctx
, CH_UNIX
, CH_DOS
, src
, src_len
,
702 (void **)dest
, converted_size
);
706 * Copy a string from a dos codepage source to a unix char* destination.
708 * The resulting string in "dest" is always null terminated.
710 * @param flags can have:
712 * <dt>STR_TERMINATE</dt>
713 * <dd>STR_TERMINATE means the string in @p src
714 * is null terminated, and src_len is ignored.</dd>
717 * @param src_len is the length of the source area in bytes.
718 * @returns the number of bytes occupied by the string in @p src.
720 size_t pull_ascii(char *dest
, const void *src
, size_t dest_len
, size_t src_len
, int flags
)
725 if (dest_len
== (size_t)-1) {
726 /* No longer allow dest_len of -1. */
727 smb_panic("pull_ascii - invalid dest_len of -1");
730 if (flags
& STR_TERMINATE
) {
731 if (src_len
== (size_t)-1) {
732 src_len
= strlen((const char *)src
) + 1;
734 size_t len
= strnlen((const char *)src
, src_len
);
741 ret
= convert_string(CH_DOS
, CH_UNIX
, src
, src_len
, dest
, dest_len
, &size
);
747 if (dest_len
&& size
) {
748 /* Did we already process the terminating zero ? */
749 if (dest
[MIN(size
-1, dest_len
-1)] != 0) {
750 dest
[MIN(size
, dest_len
-1)] = 0;
760 * Copy a string from a dos codepage source to a unix char* destination.
763 * The resulting string in "dest" is always null terminated.
765 * @param flags can have:
767 * <dt>STR_TERMINATE</dt>
768 * <dd>STR_TERMINATE means the string in @p src
769 * is null terminated, and src_len is ignored.</dd>
772 * @param src_len is the length of the source area in bytes.
773 * @returns the number of bytes occupied by the string in @p src.
776 static size_t pull_ascii_base_talloc(TALLOC_CTX
*ctx
,
791 if (src_len
== (size_t)-1) {
792 smb_panic("sec_len == -1 in pull_ascii_base_talloc");
795 if (flags
& STR_TERMINATE
) {
796 size_t len
= strnlen((const char *)src
, src_len
);
800 /* Ensure we don't use an insane length from the client. */
801 if (src_len
>= 1024*1024) {
802 char *msg
= talloc_asprintf(ctx
,
803 "Bad src length (%u) in "
804 "pull_ascii_base_talloc",
805 (unsigned int)src_len
);
810 /* src_len != -1 here. */
812 if (!convert_string_talloc(ctx
, CH_DOS
, CH_UNIX
, src
, src_len
, &dest
,
817 if (dest_len
&& dest
) {
818 /* Did we already process the terminating zero ? */
819 if (dest
[dest_len
-1] != 0) {
820 size_t size
= talloc_get_size(dest
);
821 /* Have we got space to append the '\0' ? */
822 if (size
<= dest_len
) {
824 dest
= TALLOC_REALLOC_ARRAY(ctx
, dest
, char,
828 dest_len
= (size_t)-1;
833 dest
[dest_len
] = '\0';
845 * Copy a string from a char* src to a unicode destination.
847 * @returns the number of bytes occupied by the string in the destination.
849 * @param flags can have:
852 * <dt>STR_TERMINATE <dd>means include the null termination.
853 * <dt>STR_UPPER <dd>means uppercase in the destination.
854 * <dt>STR_NOALIGN <dd>means don't do alignment.
857 * @param dest_len is the maximum length allowed in the
861 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
, &size
);
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;
980 if (dest_len
== (size_t)-1) {
981 /* No longer allow dest_len of -1. */
982 smb_panic("pull_ucs2 - invalid dest_len of -1");
986 if (dest
&& dest_len
> 0) {
992 if (ucs2_align(base_ptr
, src
, flags
)) {
993 src
= (const void *)((const char *)src
+ 1);
994 if (src_len
!= (size_t)-1)
999 if (flags
& STR_TERMINATE
) {
1000 /* src_len -1 is the default for null terminated strings. */
1001 if (src_len
!= (size_t)-1) {
1002 size_t len
= strnlen_w((const smb_ucs2_t
*)src
,
1004 if (len
< src_len
/2)
1010 /* ucs2 is always a multiple of 2 bytes */
1011 if (src_len
!= (size_t)-1)
1014 ret
= convert_string(CH_UTF16LE
, CH_UNIX
, src
, src_len
, dest
, dest_len
, &size
);
1020 if (src_len
== (size_t)-1)
1023 if (dest_len
&& size
) {
1024 /* Did we already process the terminating zero ? */
1025 if (dest
[MIN(size
-1, dest_len
-1)] != 0) {
1026 dest
[MIN(size
, dest_len
-1)] = 0;
1032 return src_len
+ ucs2_align_len
;
1036 Copy a string from a ucs2 source to a unix char* destination.
1037 Talloc version with a base pointer.
1038 Uses malloc if TALLOC_CTX is NULL (this is a bad interface and
1041 STR_TERMINATE means the string in src is null terminated.
1042 STR_NOALIGN means don't try to align.
1043 if STR_TERMINATE is set then src_len is ignored if it is -1.
1044 src_len is the length of the source area in bytes
1045 Return the number of bytes occupied by the string in src.
1046 The resulting string in "dest" is always null terminated.
1049 static size_t pull_ucs2_base_talloc(TALLOC_CTX
*ctx
,
1050 const void *base_ptr
,
1058 size_t ucs2_align_len
= 0;
1063 /* Ensure we never use the braindead "malloc" varient. */
1065 smb_panic("NULL talloc CTX in pull_ucs2_base_talloc\n");
1073 if (src_len
== (size_t)-1) {
1074 /* no longer used anywhere, but worth checking */
1075 smb_panic("sec_len == -1 in pull_ucs2_base_talloc");
1078 if (ucs2_align(base_ptr
, src
, flags
)) {
1079 src
= (const void *)((const char *)src
+ 1);
1084 if (flags
& STR_TERMINATE
) {
1085 /* src_len -1 is the default for null terminated strings. */
1086 size_t len
= strnlen_w((const smb_ucs2_t
*)src
,
1088 if (len
< src_len
/2)
1092 /* Ensure we don't use an insane length from the client. */
1093 if (src_len
>= 1024*1024) {
1094 smb_panic("Bad src length in pull_ucs2_base_talloc\n");
1098 /* ucs2 is always a multiple of 2 bytes */
1101 if (!convert_string_talloc(ctx
, CH_UTF16LE
, CH_UNIX
, src
, src_len
,
1102 (void *)&dest
, &dest_len
)) {
1107 /* Did we already process the terminating zero ? */
1108 if (dest
[dest_len
-1] != 0) {
1109 size_t size
= talloc_get_size(dest
);
1110 /* Have we got space to append the '\0' ? */
1111 if (size
<= dest_len
) {
1113 dest
= TALLOC_REALLOC_ARRAY(ctx
, dest
, char,
1117 dest_len
= (size_t)-1;
1122 dest
[dest_len
] = '\0';
1130 return src_len
+ ucs2_align_len
;
1134 * Copy a string from a UCS2 src to a unix char * destination, allocating a buffer using talloc
1136 * @param dest always set at least to NULL
1137 * @parm converted_size set to the number of bytes occupied by the string in
1138 * the destination on success.
1140 * @return true if new buffer was correctly allocated, and string was
1144 bool pull_ucs2_talloc(TALLOC_CTX
*ctx
, char **dest
, const smb_ucs2_t
*src
,
1145 size_t *converted_size
)
1147 size_t src_len
= (strlen_w(src
)+1) * sizeof(smb_ucs2_t
);
1150 return convert_string_talloc(ctx
, CH_UTF16LE
, CH_UNIX
, src
, src_len
,
1151 (void **)dest
, converted_size
);
1155 * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer using talloc
1157 * @param dest always set at least to NULL
1158 * @parm converted_size set to the number of bytes occupied by the string in
1159 * the destination on success.
1161 * @return true if new buffer was correctly allocated, and string was
1165 bool pull_utf8_talloc(TALLOC_CTX
*ctx
, char **dest
, const char *src
,
1166 size_t *converted_size
)
1168 size_t src_len
= strlen(src
)+1;
1171 return convert_string_talloc(ctx
, CH_UTF8
, CH_UNIX
, src
, src_len
,
1172 (void **)dest
, converted_size
);
1177 * Copy a string from a DOS src to a unix char * destination, allocating a buffer using talloc
1179 * @param dest always set at least to NULL
1180 * @parm converted_size set to the number of bytes occupied by the string in
1181 * the destination on success.
1183 * @return true if new buffer was correctly allocated, and string was
1187 bool pull_ascii_talloc(TALLOC_CTX
*ctx
, char **dest
, const char *src
,
1188 size_t *converted_size
)
1190 size_t src_len
= strlen(src
)+1;
1193 return convert_string_talloc(ctx
, CH_DOS
, CH_UNIX
, src
, src_len
,
1194 (void **)dest
, converted_size
);
1198 Copy a string from a char* src to a unicode or ascii
1199 dos codepage destination choosing unicode or ascii based on the
1201 Return the number of bytes occupied by the string in the destination.
1203 STR_TERMINATE means include the null termination.
1204 STR_UPPER means uppercase in the destination.
1205 STR_ASCII use ascii even with unicode packet.
1206 STR_NOALIGN means don't do alignment.
1207 dest_len is the maximum length allowed in the destination. If dest_len
1208 is -1 then no maxiumum is used.
1211 size_t push_string_check_fn(void *dest
, const char *src
,
1212 size_t dest_len
, int flags
)
1214 if (!(flags
& STR_ASCII
) && (flags
& STR_UNICODE
)) {
1215 return push_ucs2(NULL
, dest
, src
, dest_len
, flags
);
1217 return push_ascii(dest
, src
, dest_len
, flags
);
1222 Copy a string from a char* src to a unicode or ascii
1223 dos codepage destination choosing unicode or ascii based on the
1224 flags in the SMB buffer starting at base_ptr.
1225 Return the number of bytes occupied by the string in the destination.
1227 STR_TERMINATE means include the null termination.
1228 STR_UPPER means uppercase in the destination.
1229 STR_ASCII use ascii even with unicode packet.
1230 STR_NOALIGN means don't do alignment.
1231 dest_len is the maximum length allowed in the destination. If dest_len
1232 is -1 then no maxiumum is used.
1235 size_t push_string_base(const char *base
, uint16 flags2
,
1236 void *dest
, const char *src
,
1237 size_t dest_len
, int flags
)
1240 if (!(flags
& STR_ASCII
) && \
1241 ((flags
& STR_UNICODE
|| \
1242 (flags2
& FLAGS2_UNICODE_STRINGS
)))) {
1243 return push_ucs2(base
, dest
, src
, dest_len
, flags
);
1245 return push_ascii(dest
, src
, dest_len
, flags
);
1249 Copy a string from a char* src to a unicode or ascii
1250 dos codepage destination choosing unicode or ascii based on the
1252 Return the number of bytes occupied by the string in the destination.
1254 STR_TERMINATE means include the null termination.
1255 STR_UPPER means uppercase in the destination.
1256 STR_ASCII use ascii even with unicode packet.
1257 STR_NOALIGN means don't do alignment.
1258 dest_len is the maximum length allowed in the destination. If dest_len
1259 is -1 then no maxiumum is used.
1262 ssize_t
push_string(void *dest
, const char *src
, size_t dest_len
, int flags
)
1266 if (!(flags
& STR_ASCII
) && \
1267 (flags
& STR_UNICODE
)) {
1268 ret
= push_ucs2(NULL
, dest
, src
, dest_len
, flags
);
1270 ret
= push_ascii(dest
, src
, dest_len
, flags
);
1272 if (ret
== (size_t)-1) {
1279 Copy a string from a unicode or ascii source (depending on
1280 the packet flags) to a char* destination.
1282 STR_TERMINATE means the string in src is null terminated.
1283 STR_UNICODE means to force as unicode.
1284 STR_ASCII use ascii even with unicode packet.
1285 STR_NOALIGN means don't do alignment.
1286 if STR_TERMINATE is set then src_len is ignored is it is -1
1287 src_len is the length of the source area in bytes.
1288 Return the number of bytes occupied by the string in src.
1289 The resulting string in "dest" is always null terminated.
1292 size_t pull_string_fn(const void *base_ptr
,
1300 if ((base_ptr
== NULL
) && ((flags
& (STR_ASCII
|STR_UNICODE
)) == 0)) {
1301 smb_panic("No base ptr to get flg2 and neither ASCII nor "
1305 if (!(flags
& STR_ASCII
) && \
1306 ((flags
& STR_UNICODE
|| \
1307 (smb_flags2
& FLAGS2_UNICODE_STRINGS
)))) {
1308 return pull_ucs2(base_ptr
, dest
, src
, dest_len
, src_len
, flags
);
1310 return pull_ascii(dest
, src
, dest_len
, src_len
, flags
);
1314 Copy a string from a unicode or ascii source (depending on
1315 the packet flags) to a char* destination.
1316 Variant that uses talloc.
1318 STR_TERMINATE means the string in src is null terminated.
1319 STR_UNICODE means to force as unicode.
1320 STR_ASCII use ascii even with unicode packet.
1321 STR_NOALIGN means don't do alignment.
1322 if STR_TERMINATE is set then src_len is ignored is it is -1
1323 src_len is the length of the source area in bytes.
1324 Return the number of bytes occupied by the string in src.
1325 The resulting string in "dest" is always null terminated.
1328 size_t pull_string_talloc(TALLOC_CTX
*ctx
,
1329 const void *base_ptr
,
1336 if ((base_ptr
== NULL
) && ((flags
& (STR_ASCII
|STR_UNICODE
)) == 0)) {
1337 smb_panic("No base ptr to get flg2 and neither ASCII nor "
1341 if (!(flags
& STR_ASCII
) && \
1342 ((flags
& STR_UNICODE
|| \
1343 (smb_flags2
& FLAGS2_UNICODE_STRINGS
)))) {
1344 return pull_ucs2_base_talloc(ctx
,
1351 return pull_ascii_base_talloc(ctx
,
1359 size_t align_string(const void *base_ptr
, const char *p
, int flags
)
1361 if (!(flags
& STR_ASCII
) && \
1362 ((flags
& STR_UNICODE
|| \
1363 (SVAL(base_ptr
, smb_flg2
) & FLAGS2_UNICODE_STRINGS
)))) {
1364 return ucs2_align(base_ptr
, p
, flags
);