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 conv_silent
; /* Should we do a debug if the conversion fails ? */
49 static bool initialized
;
51 void lazy_initialize_conv(void)
54 load_case_tables_library();
61 * Destroy global objects allocated by init_iconv()
63 void gfree_charcnv(void)
65 TALLOC_FREE(global_iconv_convenience
);
70 * Initialize iconv conversion descriptors.
72 * This is called the first time it is needed, and also called again
73 * every time the configuration is reloaded, because the charset or
74 * codepage might have changed.
78 global_iconv_convenience
= smb_iconv_convenience_reinit(NULL
, lp_dos_charset(),
79 lp_unix_charset(), lp_display_charset(),
80 true, global_iconv_convenience
);
84 * Convert string from one encoding to another, making error checking etc
85 * Slow path version - uses (slow) iconv.
87 * @param src pointer to source string (multibyte or singlebyte)
88 * @param srclen length of the source string in bytes
89 * @param dest pointer to destination string (multibyte or singlebyte)
90 * @param destlen maximal length allowed for string
91 * @param allow_bad_conv determines if a "best effort" conversion is acceptable (never returns errors)
92 * @returns the number of bytes occupied in the destination
94 * Ensure the srclen contains the terminating zero.
98 static size_t convert_string_internal(charset_t from
, charset_t to
,
99 void const *src
, size_t srclen
,
100 void *dest
, size_t destlen
, bool allow_bad_conv
)
104 const char* inbuf
= (const char*)src
;
105 char* outbuf
= (char*)dest
;
106 smb_iconv_t descriptor
;
107 struct smb_iconv_convenience
*ic
;
109 lazy_initialize_conv();
110 ic
= get_iconv_convenience();
111 descriptor
= get_conv_handle(ic
, from
, to
);
113 if (srclen
== (size_t)-1) {
114 if (from
== CH_UTF16LE
|| from
== CH_UTF16BE
) {
115 srclen
= (strlen_w((const smb_ucs2_t
*)src
)+1) * 2;
117 srclen
= strlen((const char *)src
)+1;
122 if (descriptor
== (smb_iconv_t
)-1 || descriptor
== (smb_iconv_t
)0) {
124 DEBUG(0,("convert_string_internal: Conversion not supported.\n"));
133 retval
= smb_iconv(descriptor
, &inbuf
, &i_len
, &outbuf
, &o_len
);
134 if(retval
==(size_t)-1) {
135 const char *reason
="unknown error";
138 reason
="Incomplete multibyte sequence";
140 DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",reason
,inbuf
));
145 reason
="No more room";
147 if (from
== CH_UNIX
) {
148 DEBUG(3,("E2BIG: convert_string(%s,%s): srclen=%u destlen=%u - '%s'\n",
149 charset_name(ic
, from
), charset_name(ic
, to
),
150 (unsigned int)srclen
, (unsigned int)destlen
, (const char *)src
));
152 DEBUG(3,("E2BIG: convert_string(%s,%s): srclen=%u destlen=%u\n",
153 charset_name(ic
, from
), charset_name(ic
, to
),
154 (unsigned int)srclen
, (unsigned int)destlen
));
159 reason
="Illegal multibyte sequence";
161 DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",reason
,inbuf
));
168 DEBUG(0,("convert_string_internal: Conversion error: %s(%s)\n",reason
,inbuf
));
171 /* smb_panic(reason); */
173 return destlen
-o_len
;
178 * Conversion not supported. This is actually an error, but there are so
179 * many misconfigured iconv systems and smb.conf's out there we can't just
180 * fail. Do a very bad conversion instead.... JRA.
184 if (o_len
== 0 || i_len
== 0)
185 return destlen
- o_len
;
187 if (((from
== CH_UTF16LE
)||(from
== CH_UTF16BE
)) &&
188 ((to
!= CH_UTF16LE
)||(to
!= CH_UTF16BE
))) {
189 /* Can't convert from utf16 any endian to multibyte.
190 Replace with the default fail char.
193 return destlen
- o_len
;
195 *outbuf
= lp_failed_convert_char();
204 if (o_len
== 0 || i_len
== 0)
205 return destlen
- o_len
;
207 /* Keep trying with the next char... */
210 } else if (from
!= CH_UTF16LE
&& from
!= CH_UTF16BE
&& to
== CH_UTF16LE
) {
211 /* Can't convert to UTF16LE - just widen by adding the
212 default fail char then zero.
215 return destlen
- o_len
;
217 outbuf
[0] = lp_failed_convert_char();
226 if (o_len
== 0 || i_len
== 0)
227 return destlen
- o_len
;
229 /* Keep trying with the next char... */
232 } else if (from
!= CH_UTF16LE
&& from
!= CH_UTF16BE
&&
233 to
!= CH_UTF16LE
&& to
!= CH_UTF16BE
) {
234 /* Failed multibyte to multibyte. Just copy the default fail char and
236 outbuf
[0] = lp_failed_convert_char();
244 if (o_len
== 0 || i_len
== 0)
245 return destlen
- o_len
;
247 /* Keep trying with the next char... */
251 /* Keep compiler happy.... */
252 return destlen
- o_len
;
258 * Convert string from one encoding to another, making error checking etc
259 * Fast path version - handles ASCII first.
261 * @param src pointer to source string (multibyte or singlebyte)
262 * @param srclen length of the source string in bytes, or -1 for nul terminated.
263 * @param dest pointer to destination string (multibyte or singlebyte)
264 * @param destlen maximal length allowed for string - *NEVER* -1.
265 * @param allow_bad_conv determines if a "best effort" conversion is acceptable (never returns errors)
266 * @returns the number of bytes occupied in the destination
268 * Ensure the srclen contains the terminating zero.
270 * This function has been hand-tuned to provide a fast path.
271 * Don't change unless you really know what you are doing. JRA.
274 size_t convert_string(charset_t from
, charset_t to
,
275 void const *src
, size_t srclen
,
276 void *dest
, size_t destlen
, bool allow_bad_conv
)
279 * NB. We deliberately don't do a strlen here if srclen == -1.
280 * This is very expensive over millions of calls and is taken
281 * care of in the slow path in convert_string_internal. JRA.
285 SMB_ASSERT(destlen
!= (size_t)-1);
291 if (from
!= CH_UTF16LE
&& from
!= CH_UTF16BE
&& to
!= CH_UTF16LE
&& to
!= CH_UTF16BE
) {
292 const unsigned char *p
= (const unsigned char *)src
;
293 unsigned char *q
= (unsigned char *)dest
;
294 size_t slen
= srclen
;
295 size_t dlen
= destlen
;
296 unsigned char lastp
= '\0';
299 /* If all characters are ascii, fast path here. */
300 while (slen
&& dlen
) {
301 if ((lastp
= *p
) <= 0x7f) {
303 if (slen
!= (size_t)-1) {
311 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
314 size_t ret
= convert_string_internal(from
, to
, p
, slen
, q
, dlen
, allow_bad_conv
);
315 if (ret
== (size_t)-1) {
323 /* Even if we fast path we should note if we ran out of room. */
324 if (((slen
!= (size_t)-1) && slen
) ||
325 ((slen
== (size_t)-1) && lastp
)) {
330 } else if (from
== CH_UTF16LE
&& to
!= CH_UTF16LE
) {
331 const unsigned char *p
= (const unsigned char *)src
;
332 unsigned char *q
= (unsigned char *)dest
;
334 size_t slen
= srclen
;
335 size_t dlen
= destlen
;
336 unsigned char lastp
= '\0';
338 /* If all characters are ascii, fast path here. */
339 while (((slen
== (size_t)-1) || (slen
>= 2)) && dlen
) {
340 if (((lastp
= *p
) <= 0x7f) && (p
[1] == 0)) {
342 if (slen
!= (size_t)-1) {
351 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
354 size_t ret
= convert_string_internal(from
, to
, p
, slen
, q
, dlen
, allow_bad_conv
);
355 if (ret
== (size_t)-1) {
363 /* Even if we fast path we should note if we ran out of room. */
364 if (((slen
!= (size_t)-1) && slen
) ||
365 ((slen
== (size_t)-1) && lastp
)) {
370 } else if (from
!= CH_UTF16LE
&& from
!= CH_UTF16BE
&& to
== CH_UTF16LE
) {
371 const unsigned char *p
= (const unsigned char *)src
;
372 unsigned char *q
= (unsigned char *)dest
;
374 size_t slen
= srclen
;
375 size_t dlen
= destlen
;
376 unsigned char lastp
= '\0';
378 /* If all characters are ascii, fast path here. */
379 while (slen
&& (dlen
>= 2)) {
380 if ((lastp
= *p
) <= 0x7F) {
383 if (slen
!= (size_t)-1) {
391 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
394 size_t ret
= convert_string_internal(from
, to
, p
, slen
, q
, dlen
, allow_bad_conv
);
395 if (ret
== (size_t)-1) {
403 /* Even if we fast path we should note if we ran out of room. */
404 if (((slen
!= (size_t)-1) && slen
) ||
405 ((slen
== (size_t)-1) && lastp
)) {
412 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
415 return convert_string_internal(from
, to
, src
, srclen
, dest
, destlen
, allow_bad_conv
);
419 * Convert between character sets, allocating a new buffer using talloc for the result.
421 * @param srclen length of source buffer.
422 * @param dest always set at least to NULL
423 * @parm converted_size set to the number of bytes occupied by the string in
424 * the destination on success.
425 * @note -1 is not accepted for srclen.
427 * @return true if new buffer was correctly allocated, and string was
430 * Ensure the srclen contains the terminating zero.
432 * I hate the goto's in this function. It's embarressing.....
433 * There has to be a cleaner way to do this. JRA.
435 bool convert_string_talloc(TALLOC_CTX
*ctx
, charset_t from
, charset_t to
,
436 void const *src
, size_t srclen
, void *dst
,
437 size_t *converted_size
, bool allow_bad_conv
)
440 size_t i_len
, o_len
, destlen
= (srclen
* 3) / 2;
442 const char *inbuf
= (const char *)src
;
443 char *outbuf
= NULL
, *ob
= NULL
;
444 smb_iconv_t descriptor
;
445 void **dest
= (void **)dst
;
446 struct smb_iconv_convenience
*ic
;
450 if (!converted_size
) {
455 if (src
== NULL
|| srclen
== (size_t)-1) {
460 ob
= talloc_strdup(ctx
, "");
470 lazy_initialize_conv();
471 ic
= get_iconv_convenience();
472 descriptor
= get_conv_handle(ic
, from
, to
);
474 if (descriptor
== (smb_iconv_t
)-1 || descriptor
== (smb_iconv_t
)0) {
476 DEBUG(0,("convert_string_talloc: Conversion not supported.\n"));
483 /* +2 is for ucs2 null termination. */
484 if ((destlen
*2)+2 < destlen
) {
485 /* wrapped ! abort. */
487 DEBUG(0, ("convert_string_talloc: destlen wrapped !\n"));
492 destlen
= destlen
* 2;
495 /* +2 is for ucs2 null termination. */
496 ob
= (char *)TALLOC_REALLOC(ctx
, ob
, destlen
+ 2);
499 DEBUG(0, ("convert_string_talloc: realloc failed!\n"));
509 retval
= smb_iconv(descriptor
,
512 if(retval
== (size_t)-1) {
513 const char *reason
="unknown error";
516 reason
="Incomplete multibyte sequence";
518 DEBUG(3,("convert_string_talloc: Conversion error: %s(%s)\n",reason
,inbuf
));
525 reason
="Illegal multibyte sequence";
527 DEBUG(3,("convert_string_talloc: Conversion error: %s(%s)\n",reason
,inbuf
));
533 DEBUG(0,("Conversion error: %s(%s)\n",reason
,inbuf
));
534 /* smb_panic(reason); */
541 destlen
= destlen
- o_len
;
542 /* Don't shrink unless we're reclaiming a lot of
543 * space. This is in the hot codepath and these
544 * reallocs *cost*. JRA.
547 /* We're shrinking here so we know the +2 is safe from wrap. */
548 ob
= (char *)TALLOC_REALLOC(ctx
,ob
,destlen
+ 2);
551 if (destlen
&& !ob
) {
552 DEBUG(0, ("convert_string_talloc: out of memory!\n"));
559 /* Must ucs2 null terminate in the extra space we allocated. */
561 ob
[destlen
+1] = '\0';
563 *converted_size
= destlen
;
569 * Conversion not supported. This is actually an error, but there are so
570 * many misconfigured iconv systems and smb.conf's out there we can't just
571 * fail. Do a very bad conversion instead.... JRA.
575 if (o_len
== 0 || i_len
== 0)
578 if (((from
== CH_UTF16LE
)||(from
== CH_UTF16BE
)) &&
579 ((to
!= CH_UTF16LE
)||(to
!= CH_UTF16BE
))) {
580 /* Can't convert from utf16 any endian to multibyte.
581 Replace with the default fail char.
588 *outbuf
= lp_failed_convert_char();
597 if (o_len
== 0 || i_len
== 0)
600 /* Keep trying with the next char... */
603 } else if (from
!= CH_UTF16LE
&& from
!= CH_UTF16BE
&& to
== CH_UTF16LE
) {
604 /* Can't convert to UTF16LE - just widen by adding the
605 default fail char then zero.
610 outbuf
[0] = lp_failed_convert_char();
619 if (o_len
== 0 || i_len
== 0)
622 /* Keep trying with the next char... */
625 } else if (from
!= CH_UTF16LE
&& from
!= CH_UTF16BE
&&
626 to
!= CH_UTF16LE
&& to
!= CH_UTF16BE
) {
627 /* Failed multibyte to multibyte. Just copy the default fail char and
629 outbuf
[0] = lp_failed_convert_char();
637 if (o_len
== 0 || i_len
== 0)
640 /* Keep trying with the next char... */
644 /* Keep compiler happy.... */
650 size_t unix_strupper(const char *src
, size_t srclen
, char *dest
, size_t destlen
)
655 if (!push_ucs2_talloc(talloc_tos(), &buffer
, src
, &size
)) {
659 if (!strupper_w(buffer
) && (dest
== src
)) {
664 size
= convert_string(CH_UTF16LE
, CH_UNIX
, buffer
, size
, dest
, destlen
, True
);
670 talloc_strdup() a unix string to upper case.
673 char *talloc_strdup_upper(TALLOC_CTX
*ctx
, const char *s
)
675 char *out_buffer
= talloc_strdup(ctx
,s
);
676 const unsigned char *p
= (const unsigned char *)s
;
677 unsigned char *q
= (unsigned char *)out_buffer
;
683 /* this is quite a common operation, so we want it to be
684 fast. We optimise for the ascii case, knowing that all our
685 supported multi-byte character sets are ascii-compatible
686 (ie. they match for the first 128 chars) */
691 *q
++ = toupper_ascii_fast(*p
);
697 size_t converted_size
, converted_size2
;
698 smb_ucs2_t
*ubuf
= NULL
;
700 /* We're not using the ascii buffer above. */
701 TALLOC_FREE(out_buffer
);
703 if (!convert_string_talloc(ctx
, CH_UNIX
, CH_UTF16LE
, s
,
704 strlen(s
)+1, (void *)&ubuf
,
705 &converted_size
, True
))
712 if (!convert_string_talloc(ctx
, CH_UTF16LE
, CH_UNIX
, ubuf
,
713 converted_size
, (void *)&out_buffer
,
714 &converted_size2
, True
))
720 /* Don't need the intermediate buffer
729 char *strupper_talloc(TALLOC_CTX
*ctx
, const char *s
) {
730 return talloc_strdup_upper(ctx
, s
);
734 size_t unix_strlower(const char *src
, size_t srclen
, char *dest
, size_t destlen
)
737 smb_ucs2_t
*buffer
= NULL
;
739 if (!convert_string_talloc(talloc_tos(), CH_UNIX
, CH_UTF16LE
, src
, srclen
,
740 (void **)(void *)&buffer
, &size
,
743 smb_panic("failed to create UCS2 buffer");
745 if (!strlower_w(buffer
) && (dest
== src
)) {
749 size
= convert_string(CH_UTF16LE
, CH_UNIX
, buffer
, size
, dest
, destlen
, True
);
755 char *talloc_strdup_lower(TALLOC_CTX
*ctx
, const char *s
)
757 size_t converted_size
;
758 smb_ucs2_t
*buffer
= NULL
;
761 if (!push_ucs2_talloc(ctx
, &buffer
, s
, &converted_size
)) {
767 if (!pull_ucs2_talloc(ctx
, &out_buffer
, buffer
, &converted_size
)) {
777 char *strlower_talloc(TALLOC_CTX
*ctx
, const char *s
) {
778 return talloc_strdup_lower(ctx
, s
);
781 size_t ucs2_align(const void *base_ptr
, const void *p
, int flags
)
783 if (flags
& (STR_NOALIGN
|STR_ASCII
))
785 return PTR_DIFF(p
, base_ptr
) & 1;
790 * Copy a string from a char* unix src to a dos codepage string destination.
792 * @return the number of bytes occupied by the string in the destination.
794 * @param flags can include
796 * <dt>STR_TERMINATE</dt> <dd>means include the null termination</dd>
797 * <dt>STR_UPPER</dt> <dd>means uppercase in the destination</dd>
800 * @param dest_len the maximum length in bytes allowed in the
803 size_t push_ascii(void *dest
, const char *src
, size_t dest_len
, int flags
)
805 size_t src_len
= strlen(src
);
809 /* No longer allow a length of -1. */
810 if (dest_len
== (size_t)-1) {
811 smb_panic("push_ascii - dest_len == -1");
814 if (flags
& STR_UPPER
) {
815 tmpbuf
= SMB_STRDUP(src
);
817 smb_panic("malloc fail");
823 if (flags
& (STR_TERMINATE
| STR_TERMINATE_ASCII
)) {
827 ret
= convert_string(CH_UNIX
, CH_DOS
, src
, src_len
, dest
, dest_len
, True
);
828 if (ret
== (size_t)-1 &&
829 (flags
& (STR_TERMINATE
| STR_TERMINATE_ASCII
))
831 ((char *)dest
)[0] = '\0';
837 size_t push_ascii_fstring(void *dest
, const char *src
)
839 return push_ascii(dest
, src
, sizeof(fstring
), STR_TERMINATE
);
842 /********************************************************************
843 Push an nstring - ensure null terminated. Written by
844 moriyama@miraclelinux.com (MORIYAMA Masayuki).
845 ********************************************************************/
847 size_t push_ascii_nstring(void *dest
, const char *src
)
849 size_t i
, buffer_len
, dest_len
;
853 if (!push_ucs2_talloc(talloc_tos(), &buffer
, src
, &buffer_len
)) {
854 smb_panic("failed to create UCS2 buffer");
857 /* We're using buffer_len below to count ucs2 characters, not bytes. */
858 buffer_len
/= sizeof(smb_ucs2_t
);
861 for (i
= 0; buffer
[i
] != 0 && (i
< buffer_len
); i
++) {
862 unsigned char mb
[10];
863 /* Convert one smb_ucs2_t character at a time. */
864 size_t mb_len
= convert_string(CH_UTF16LE
, CH_DOS
, buffer
+i
, sizeof(smb_ucs2_t
), mb
, sizeof(mb
), False
);
865 if ((mb_len
!= (size_t)-1) && (dest_len
+ mb_len
<= MAX_NETBIOSNAME_LEN
- 1)) {
866 memcpy((char *)dest
+ dest_len
, mb
, mb_len
);
873 ((char *)dest
)[dest_len
] = '\0';
880 /********************************************************************
881 Push and malloc an ascii string. src and dest null terminated.
882 ********************************************************************/
884 bool push_ascii_talloc(TALLOC_CTX
*mem_ctx
, char **dest
, const char *src
, size_t *converted_size
)
886 size_t src_len
= strlen(src
)+1;
889 return convert_string_talloc(mem_ctx
, CH_UNIX
, CH_DOS
, src
, src_len
,
890 (void **)dest
, converted_size
, True
);
894 * Copy a string from a dos codepage source to a unix char* destination.
896 * The resulting string in "dest" is always null terminated.
898 * @param flags can have:
900 * <dt>STR_TERMINATE</dt>
901 * <dd>STR_TERMINATE means the string in @p src
902 * is null terminated, and src_len is ignored.</dd>
905 * @param src_len is the length of the source area in bytes.
906 * @returns the number of bytes occupied by the string in @p src.
908 size_t pull_ascii(char *dest
, const void *src
, size_t dest_len
, size_t src_len
, int flags
)
912 if (dest_len
== (size_t)-1) {
913 /* No longer allow dest_len of -1. */
914 smb_panic("pull_ascii - invalid dest_len of -1");
917 if (flags
& STR_TERMINATE
) {
918 if (src_len
== (size_t)-1) {
919 src_len
= strlen((const char *)src
) + 1;
921 size_t len
= strnlen((const char *)src
, src_len
);
928 ret
= convert_string(CH_DOS
, CH_UNIX
, src
, src_len
, dest
, dest_len
, True
);
929 if (ret
== (size_t)-1) {
934 if (dest_len
&& ret
) {
935 /* Did we already process the terminating zero ? */
936 if (dest
[MIN(ret
-1, dest_len
-1)] != 0) {
937 dest
[MIN(ret
, dest_len
-1)] = 0;
947 * Copy a string from a dos codepage source to a unix char* destination.
950 * The resulting string in "dest" is always null terminated.
952 * @param flags can have:
954 * <dt>STR_TERMINATE</dt>
955 * <dd>STR_TERMINATE means the string in @p src
956 * is null terminated, and src_len is ignored.</dd>
959 * @param src_len is the length of the source area in bytes.
960 * @returns the number of bytes occupied by the string in @p src.
963 static size_t pull_ascii_base_talloc(TALLOC_CTX
*ctx
,
978 if (flags
& STR_TERMINATE
) {
979 if (src_len
== (size_t)-1) {
980 src_len
= strlen((const char *)src
) + 1;
982 size_t len
= strnlen((const char *)src
, src_len
);
987 /* Ensure we don't use an insane length from the client. */
988 if (src_len
>= 1024*1024) {
989 char *msg
= talloc_asprintf(ctx
,
990 "Bad src length (%u) in "
991 "pull_ascii_base_talloc",
992 (unsigned int)src_len
);
996 /* Can't have an unlimited length
997 * non STR_TERMINATE'd.
999 if (src_len
== (size_t)-1) {
1005 /* src_len != -1 here. */
1007 if (!convert_string_talloc(ctx
, CH_DOS
, CH_UNIX
, src
, src_len
, &dest
,
1012 if (dest_len
&& dest
) {
1013 /* Did we already process the terminating zero ? */
1014 if (dest
[dest_len
-1] != 0) {
1015 size_t size
= talloc_get_size(dest
);
1016 /* Have we got space to append the '\0' ? */
1017 if (size
<= dest_len
) {
1019 dest
= TALLOC_REALLOC_ARRAY(ctx
, dest
, char,
1023 dest_len
= (size_t)-1;
1028 dest
[dest_len
] = '\0';
1039 size_t pull_ascii_fstring(char *dest
, const void *src
)
1041 return pull_ascii(dest
, src
, sizeof(fstring
), -1, STR_TERMINATE
);
1044 /* When pulling an nstring it can expand into a larger size (dos cp -> utf8). Cope with this. */
1046 size_t pull_ascii_nstring(char *dest
, size_t dest_len
, const void *src
)
1048 return pull_ascii(dest
, src
, dest_len
, sizeof(nstring
)-1, STR_TERMINATE
);
1052 * Copy a string from a char* src to a unicode destination.
1054 * @returns the number of bytes occupied by the string in the destination.
1056 * @param flags can have:
1059 * <dt>STR_TERMINATE <dd>means include the null termination.
1060 * <dt>STR_UPPER <dd>means uppercase in the destination.
1061 * <dt>STR_NOALIGN <dd>means don't do alignment.
1064 * @param dest_len is the maximum length allowed in the
1068 size_t push_ucs2(const void *base_ptr
, void *dest
, const char *src
, size_t dest_len
, int flags
)
1074 if (dest_len
== (size_t)-1) {
1075 /* No longer allow dest_len of -1. */
1076 smb_panic("push_ucs2 - invalid dest_len of -1");
1079 if (flags
& STR_TERMINATE
)
1080 src_len
= (size_t)-1;
1082 src_len
= strlen(src
);
1084 if (ucs2_align(base_ptr
, dest
, flags
)) {
1086 dest
= (void *)((char *)dest
+ 1);
1092 /* ucs2 is always a multiple of 2 bytes */
1095 ret
= convert_string(CH_UNIX
, CH_UTF16LE
, src
, src_len
, dest
, dest_len
, True
);
1096 if (ret
== (size_t)-1) {
1097 if ((flags
& STR_TERMINATE
) &&
1107 if (flags
& STR_UPPER
) {
1108 smb_ucs2_t
*dest_ucs2
= (smb_ucs2_t
*)dest
;
1111 /* We check for i < (ret / 2) below as the dest string isn't null
1112 terminated if STR_TERMINATE isn't set. */
1114 for (i
= 0; i
< (ret
/ 2) && i
< (dest_len
/ 2) && dest_ucs2
[i
]; i
++) {
1115 smb_ucs2_t v
= toupper_m(dest_ucs2
[i
]);
1116 if (v
!= dest_ucs2
[i
]) {
1127 * Copy a string from a unix char* src to a UCS2 destination,
1128 * 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
1137 bool push_ucs2_talloc(TALLOC_CTX
*ctx
, smb_ucs2_t
**dest
, const char *src
,
1138 size_t *converted_size
)
1140 size_t src_len
= strlen(src
)+1;
1143 return convert_string_talloc(ctx
, CH_UNIX
, CH_UTF16LE
, src
, src_len
,
1144 (void **)dest
, converted_size
, True
);
1149 Copy a string from a char* src to a UTF-8 destination.
1150 Return the number of bytes occupied by the string in the destination
1152 STR_TERMINATE means include the null termination
1153 STR_UPPER means uppercase in the destination
1154 dest_len is the maximum length allowed in the destination. If dest_len
1155 is -1 then no maxiumum is used.
1158 static size_t push_utf8(void *dest
, const char *src
, size_t dest_len
, int flags
)
1162 char *tmpbuf
= NULL
;
1164 if (dest_len
== (size_t)-1) {
1165 /* No longer allow dest_len of -1. */
1166 smb_panic("push_utf8 - invalid dest_len of -1");
1169 if (flags
& STR_UPPER
) {
1170 tmpbuf
= strupper_talloc(talloc_tos(), src
);
1175 src_len
= strlen(src
);
1178 src_len
= strlen(src
);
1179 if (flags
& STR_TERMINATE
) {
1183 ret
= convert_string(CH_UNIX
, CH_UTF8
, src
, src_len
, dest
, dest_len
, True
);
1184 TALLOC_FREE(tmpbuf
);
1188 size_t push_utf8_fstring(void *dest
, const char *src
)
1190 return push_utf8(dest
, src
, sizeof(fstring
), STR_TERMINATE
);
1194 * Copy a string from a unix char* src to a UTF-8 destination, allocating a buffer using talloc
1196 * @param dest always set at least to NULL
1197 * @parm converted_size set to the number of bytes occupied by the string in
1198 * the destination on success.
1200 * @return true if new buffer was correctly allocated, and string was
1204 bool push_utf8_talloc(TALLOC_CTX
*ctx
, char **dest
, const char *src
,
1205 size_t *converted_size
)
1207 size_t src_len
= strlen(src
)+1;
1210 return convert_string_talloc(ctx
, CH_UNIX
, CH_UTF8
, src
, src_len
,
1211 (void**)dest
, converted_size
, True
);
1215 Copy a string from a ucs2 source to a unix char* destination.
1217 STR_TERMINATE means the string in src is null terminated.
1218 STR_NOALIGN means don't try to align.
1219 if STR_TERMINATE is set then src_len is ignored if it is -1.
1220 src_len is the length of the source area in bytes
1221 Return the number of bytes occupied by the string in src.
1222 The resulting string in "dest" is always null terminated.
1225 size_t pull_ucs2(const void *base_ptr
, char *dest
, const void *src
, size_t dest_len
, size_t src_len
, int flags
)
1228 size_t ucs2_align_len
= 0;
1230 if (dest_len
== (size_t)-1) {
1231 /* No longer allow dest_len of -1. */
1232 smb_panic("pull_ucs2 - invalid dest_len of -1");
1236 if (dest
&& dest_len
> 0) {
1242 if (ucs2_align(base_ptr
, src
, flags
)) {
1243 src
= (const void *)((const char *)src
+ 1);
1244 if (src_len
!= (size_t)-1)
1249 if (flags
& STR_TERMINATE
) {
1250 /* src_len -1 is the default for null terminated strings. */
1251 if (src_len
!= (size_t)-1) {
1252 size_t len
= strnlen_w((const smb_ucs2_t
*)src
,
1254 if (len
< src_len
/2)
1260 /* ucs2 is always a multiple of 2 bytes */
1261 if (src_len
!= (size_t)-1)
1264 ret
= convert_string(CH_UTF16LE
, CH_UNIX
, src
, src_len
, dest
, dest_len
, True
);
1265 if (ret
== (size_t)-1) {
1270 if (src_len
== (size_t)-1)
1273 if (dest_len
&& ret
) {
1274 /* Did we already process the terminating zero ? */
1275 if (dest
[MIN(ret
-1, dest_len
-1)] != 0) {
1276 dest
[MIN(ret
, dest_len
-1)] = 0;
1282 return src_len
+ ucs2_align_len
;
1286 Copy a string from a ucs2 source to a unix char* destination.
1287 Talloc version with a base pointer.
1288 Uses malloc if TALLOC_CTX is NULL (this is a bad interface and
1291 STR_TERMINATE means the string in src is null terminated.
1292 STR_NOALIGN means don't try to align.
1293 if STR_TERMINATE is set then src_len is ignored if it is -1.
1294 src_len is the length of the source area in bytes
1295 Return the number of bytes occupied by the string in src.
1296 The resulting string in "dest" is always null terminated.
1299 size_t pull_ucs2_base_talloc(TALLOC_CTX
*ctx
,
1300 const void *base_ptr
,
1308 size_t ucs2_align_len
= 0;
1313 /* Ensure we never use the braindead "malloc" varient. */
1315 smb_panic("NULL talloc CTX in pull_ucs2_base_talloc\n");
1323 if (ucs2_align(base_ptr
, src
, flags
)) {
1324 src
= (const void *)((const char *)src
+ 1);
1325 if (src_len
!= (size_t)-1)
1330 if (flags
& STR_TERMINATE
) {
1331 /* src_len -1 is the default for null terminated strings. */
1332 if (src_len
!= (size_t)-1) {
1333 size_t len
= strnlen_w((const smb_ucs2_t
*)src
,
1335 if (len
< src_len
/2)
1340 * src_len == -1 - alloc interface won't take this
1341 * so we must calculate.
1343 src_len
= (strlen_w((const smb_ucs2_t
*)src
)+1)*sizeof(smb_ucs2_t
);
1345 /* Ensure we don't use an insane length from the client. */
1346 if (src_len
>= 1024*1024) {
1347 smb_panic("Bad src length in pull_ucs2_base_talloc\n");
1350 /* Can't have an unlimited length
1351 * non STR_TERMINATE'd.
1353 if (src_len
== (size_t)-1) {
1359 /* src_len != -1 here. */
1361 /* ucs2 is always a multiple of 2 bytes */
1364 if (!convert_string_talloc(ctx
, CH_UTF16LE
, CH_UNIX
, src
, src_len
,
1365 (void *)&dest
, &dest_len
, True
)) {
1370 /* Did we already process the terminating zero ? */
1371 if (dest
[dest_len
-1] != 0) {
1372 size_t size
= talloc_get_size(dest
);
1373 /* Have we got space to append the '\0' ? */
1374 if (size
<= dest_len
) {
1376 dest
= TALLOC_REALLOC_ARRAY(ctx
, dest
, char,
1380 dest_len
= (size_t)-1;
1385 dest
[dest_len
] = '\0';
1393 return src_len
+ ucs2_align_len
;
1396 size_t pull_ucs2_fstring(char *dest
, const void *src
)
1398 return pull_ucs2(NULL
, dest
, src
, sizeof(fstring
), -1, STR_TERMINATE
);
1402 * Copy a string from a UCS2 src to a unix char * destination, allocating a buffer using talloc
1404 * @param dest always set at least to NULL
1405 * @parm converted_size set to the number of bytes occupied by the string in
1406 * the destination on success.
1408 * @return true if new buffer was correctly allocated, and string was
1412 bool pull_ucs2_talloc(TALLOC_CTX
*ctx
, char **dest
, const smb_ucs2_t
*src
,
1413 size_t *converted_size
)
1415 size_t src_len
= (strlen_w(src
)+1) * sizeof(smb_ucs2_t
);
1418 return convert_string_talloc(ctx
, CH_UTF16LE
, CH_UNIX
, src
, src_len
,
1419 (void **)dest
, converted_size
, True
);
1423 * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer using talloc
1425 * @param dest always set at least to NULL
1426 * @parm converted_size set to the number of bytes occupied by the string in
1427 * the destination on success.
1429 * @return true if new buffer was correctly allocated, and string was
1433 bool pull_utf8_talloc(TALLOC_CTX
*ctx
, char **dest
, const char *src
,
1434 size_t *converted_size
)
1436 size_t src_len
= strlen(src
)+1;
1439 return convert_string_talloc(ctx
, CH_UTF8
, CH_UNIX
, src
, src_len
,
1440 (void **)dest
, converted_size
, True
);
1445 * Copy a string from a DOS src to a unix char * destination, allocating a buffer using talloc
1447 * @param dest always set at least to NULL
1448 * @parm converted_size set to the number of bytes occupied by the string in
1449 * the destination on success.
1451 * @return true if new buffer was correctly allocated, and string was
1455 bool pull_ascii_talloc(TALLOC_CTX
*ctx
, char **dest
, const char *src
,
1456 size_t *converted_size
)
1458 size_t src_len
= strlen(src
)+1;
1461 return convert_string_talloc(ctx
, CH_DOS
, CH_UNIX
, src
, src_len
,
1462 (void **)dest
, converted_size
, True
);
1466 Copy a string from a char* src to a unicode or ascii
1467 dos codepage destination choosing unicode or ascii based on the
1469 Return the number of bytes occupied by the string in the destination.
1471 STR_TERMINATE means include the null termination.
1472 STR_UPPER means uppercase in the destination.
1473 STR_ASCII use ascii even with unicode packet.
1474 STR_NOALIGN means don't do alignment.
1475 dest_len is the maximum length allowed in the destination. If dest_len
1476 is -1 then no maxiumum is used.
1479 size_t push_string_check_fn(const char *function
, unsigned int line
,
1480 void *dest
, const char *src
,
1481 size_t dest_len
, int flags
)
1484 /* We really need to zero fill here, not clobber
1485 * region, as we want to ensure that valgrind thinks
1486 * all of the outgoing buffer has been written to
1487 * so a send() or write() won't trap an error.
1491 clobber_region(function
, line
, dest
, dest_len
);
1493 memset(dest
, '\0', dest_len
);
1497 if (!(flags
& STR_ASCII
) && (flags
& STR_UNICODE
)) {
1498 return push_ucs2(NULL
, dest
, src
, dest_len
, flags
);
1500 return push_ascii(dest
, src
, dest_len
, flags
);
1505 Copy a string from a char* src to a unicode or ascii
1506 dos codepage destination choosing unicode or ascii based on the
1507 flags in the SMB buffer starting at base_ptr.
1508 Return the number of bytes occupied by the string in the destination.
1510 STR_TERMINATE means include the null termination.
1511 STR_UPPER means uppercase in the destination.
1512 STR_ASCII use ascii even with unicode packet.
1513 STR_NOALIGN means don't do alignment.
1514 dest_len is the maximum length allowed in the destination. If dest_len
1515 is -1 then no maxiumum is used.
1518 size_t push_string_base(const char *function
, unsigned int line
,
1519 const char *base
, uint16 flags2
,
1520 void *dest
, const char *src
,
1521 size_t dest_len
, int flags
)
1524 /* We really need to zero fill here, not clobber
1525 * region, as we want to ensure that valgrind thinks
1526 * all of the outgoing buffer has been written to
1527 * so a send() or write() won't trap an error.
1531 clobber_region(function
, line
, dest
, dest_len
);
1533 memset(dest
, '\0', dest_len
);
1537 if (!(flags
& STR_ASCII
) && \
1538 ((flags
& STR_UNICODE
|| \
1539 (flags2
& FLAGS2_UNICODE_STRINGS
)))) {
1540 return push_ucs2(base
, dest
, src
, dest_len
, flags
);
1542 return push_ascii(dest
, src
, dest_len
, flags
);
1546 Copy a string from a char* src to a unicode or ascii
1547 dos codepage destination choosing unicode or ascii based on the
1549 Return the number of bytes occupied by the string in the destination.
1551 STR_TERMINATE means include the null termination.
1552 STR_UPPER means uppercase in the destination.
1553 STR_ASCII use ascii even with unicode packet.
1554 STR_NOALIGN means don't do alignment.
1555 dest_len is the maximum length allowed in the destination. If dest_len
1556 is -1 then no maxiumum is used.
1559 ssize_t
push_string(void *dest
, const char *src
, size_t dest_len
, int flags
)
1563 /* We really need to zero fill here, not clobber
1564 * region, as we want to ensure that valgrind thinks
1565 * all of the outgoing buffer has been written to
1566 * so a send() or write() won't trap an error.
1569 memset(dest
, '\0', dest_len
);
1572 if (!(flags
& STR_ASCII
) && \
1573 (flags
& STR_UNICODE
)) {
1574 ret
= push_ucs2(NULL
, dest
, src
, dest_len
, flags
);
1576 ret
= push_ascii(dest
, src
, dest_len
, flags
);
1578 if (ret
== (size_t)-1) {
1585 Copy a string from a unicode or ascii source (depending on
1586 the packet flags) to a char* destination.
1588 STR_TERMINATE means the string in src is null terminated.
1589 STR_UNICODE means to force as unicode.
1590 STR_ASCII use ascii even with unicode packet.
1591 STR_NOALIGN means don't do alignment.
1592 if STR_TERMINATE is set then src_len is ignored is it is -1
1593 src_len is the length of the source area in bytes.
1594 Return the number of bytes occupied by the string in src.
1595 The resulting string in "dest" is always null terminated.
1598 size_t pull_string_fn(const char *function
,
1600 const void *base_ptr
,
1609 clobber_region(function
, line
, dest
, dest_len
);
1612 if ((base_ptr
== NULL
) && ((flags
& (STR_ASCII
|STR_UNICODE
)) == 0)) {
1613 smb_panic("No base ptr to get flg2 and neither ASCII nor "
1617 if (!(flags
& STR_ASCII
) && \
1618 ((flags
& STR_UNICODE
|| \
1619 (smb_flags2
& FLAGS2_UNICODE_STRINGS
)))) {
1620 return pull_ucs2(base_ptr
, dest
, src
, dest_len
, src_len
, flags
);
1622 return pull_ascii(dest
, src
, dest_len
, src_len
, flags
);
1626 Copy a string from a unicode or ascii source (depending on
1627 the packet flags) to a char* destination.
1628 Variant that uses talloc.
1630 STR_TERMINATE means the string in src is null terminated.
1631 STR_UNICODE means to force as unicode.
1632 STR_ASCII use ascii even with unicode packet.
1633 STR_NOALIGN means don't do alignment.
1634 if STR_TERMINATE is set then src_len is ignored is it is -1
1635 src_len is the length of the source area in bytes.
1636 Return the number of bytes occupied by the string in src.
1637 The resulting string in "dest" is always null terminated.
1640 size_t pull_string_talloc_fn(const char *function
,
1643 const void *base_ptr
,
1650 if ((base_ptr
== NULL
) && ((flags
& (STR_ASCII
|STR_UNICODE
)) == 0)) {
1651 smb_panic("No base ptr to get flg2 and neither ASCII nor "
1655 if (!(flags
& STR_ASCII
) && \
1656 ((flags
& STR_UNICODE
|| \
1657 (smb_flags2
& FLAGS2_UNICODE_STRINGS
)))) {
1658 return pull_ucs2_base_talloc(ctx
,
1665 return pull_ascii_base_talloc(ctx
,
1673 size_t align_string(const void *base_ptr
, const char *p
, int flags
)
1675 if (!(flags
& STR_ASCII
) && \
1676 ((flags
& STR_UNICODE
|| \
1677 (SVAL(base_ptr
, smb_flg2
) & FLAGS2_UNICODE_STRINGS
)))) {
1678 return ucs2_align(base_ptr
, p
, flags
);