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/>.
26 * Destroy global objects allocated by init_iconv()
28 void gfree_charcnv(void)
30 TALLOC_FREE(global_iconv_handle
);
34 * Copy a string from a char* unix src to a dos codepage string destination.
36 * @return the number of bytes occupied by the string in the destination.
38 * @param flags can include
40 * <dt>STR_TERMINATE</dt> <dd>means include the null termination</dd>
41 * <dt>STR_UPPER</dt> <dd>means uppercase in the destination</dd>
44 * @param dest_len the maximum length in bytes allowed in the
47 size_t push_ascii(void *dest
, const char *src
, size_t dest_len
, int flags
)
49 size_t src_len
= strlen(src
);
54 /* No longer allow a length of -1. */
55 if (dest_len
== (size_t)-1) {
56 smb_panic("push_ascii - dest_len == -1");
59 if (flags
& STR_UPPER
) {
60 tmpbuf
= SMB_STRDUP(src
);
62 smb_panic("malloc fail");
68 if (flags
& (STR_TERMINATE
| STR_TERMINATE_ASCII
)) {
72 ret
= convert_string(CH_UNIX
, CH_DOS
, src
, src_len
, dest
, dest_len
, &size
);
74 (flags
& (STR_TERMINATE
| STR_TERMINATE_ASCII
))
76 ((char *)dest
)[0] = '\0';
79 return ret
? size
: (size_t)-1;
82 /********************************************************************
83 Push and malloc an ascii string. src and dest null terminated.
84 ********************************************************************/
87 * Copy a string from a dos codepage source to a unix char* destination.
89 * The resulting string in "dest" is always null terminated.
91 * @param flags can have:
93 * <dt>STR_TERMINATE</dt>
94 * <dd>STR_TERMINATE means the string in @p src
95 * is null terminated, and src_len is ignored.</dd>
98 * @param src_len is the length of the source area in bytes.
99 * @returns the number of bytes occupied by the string in @p src.
101 size_t pull_ascii(char *dest
, const void *src
, size_t dest_len
, size_t src_len
, int flags
)
106 if (dest_len
== (size_t)-1) {
107 /* No longer allow dest_len of -1. */
108 smb_panic("pull_ascii - invalid dest_len of -1");
111 if (flags
& STR_TERMINATE
) {
112 if (src_len
== (size_t)-1) {
113 src_len
= strlen((const char *)src
) + 1;
115 size_t len
= strnlen((const char *)src
, src_len
);
122 ret
= convert_string(CH_DOS
, CH_UNIX
, src
, src_len
, dest
, dest_len
, &size
);
128 if (dest_len
&& size
) {
129 /* Did we already process the terminating zero ? */
130 if (dest
[MIN(size
-1, dest_len
-1)] != 0) {
131 dest
[MIN(size
, dest_len
-1)] = 0;
141 * Copy a string from a dos codepage source to a unix char* destination.
144 * The resulting string in "dest" is always null terminated.
146 * @param flags can have:
148 * <dt>STR_TERMINATE</dt>
149 * <dd>STR_TERMINATE means the string in @p src
150 * is null terminated, and src_len is ignored.</dd>
153 * @param src_len is the length of the source area in bytes.
154 * @returns the number of bytes occupied by the string in @p src.
157 static size_t pull_ascii_base_talloc(TALLOC_CTX
*ctx
,
172 if (src_len
== (size_t)-1) {
173 smb_panic("sec_len == -1 in pull_ascii_base_talloc");
176 if (flags
& STR_TERMINATE
) {
177 size_t len
= strnlen((const char *)src
, src_len
);
181 /* Ensure we don't use an insane length from the client. */
182 if (src_len
>= 1024*1024) {
183 char *msg
= talloc_asprintf(ctx
,
184 "Bad src length (%u) in "
185 "pull_ascii_base_talloc",
186 (unsigned int)src_len
);
191 /* src_len != -1 here. */
193 if (!convert_string_talloc(ctx
, CH_DOS
, CH_UNIX
, src
, src_len
, &dest
,
198 if (dest_len
&& dest
) {
199 /* Did we already process the terminating zero ? */
200 if (dest
[dest_len
-1] != 0) {
201 size_t size
= talloc_get_size(dest
);
202 /* Have we got space to append the '\0' ? */
203 if (size
<= dest_len
) {
205 dest
= talloc_realloc(ctx
, dest
, char,
209 dest_len
= (size_t)-1;
214 dest
[dest_len
] = '\0';
226 * Copy a string from a char* src to a unicode destination.
228 * @returns the number of bytes occupied by the string in the destination.
230 * @param flags can have:
233 * <dt>STR_TERMINATE <dd>means include the null termination.
234 * <dt>STR_UPPER <dd>means uppercase in the destination.
235 * <dt>STR_NOALIGN <dd>means don't do alignment.
238 * @param dest_len is the maximum length allowed in the
242 static size_t push_ucs2(const void *base_ptr
, void *dest
, const char *src
, size_t dest_len
, int flags
)
249 if (dest_len
== (size_t)-1) {
250 /* No longer allow dest_len of -1. */
251 smb_panic("push_ucs2 - invalid dest_len of -1");
254 if (flags
& STR_TERMINATE
)
255 src_len
= (size_t)-1;
257 src_len
= strlen(src
);
259 if (ucs2_align(base_ptr
, dest
, flags
)) {
261 dest
= (void *)((char *)dest
+ 1);
267 /* ucs2 is always a multiple of 2 bytes */
270 ret
= convert_string(CH_UNIX
, CH_UTF16LE
, src
, src_len
, dest
, dest_len
, &size
);
272 if ((flags
& STR_TERMINATE
) &&
282 if (flags
& STR_UPPER
) {
283 smb_ucs2_t
*dest_ucs2
= (smb_ucs2_t
*)dest
;
286 /* We check for i < (ret / 2) below as the dest string isn't null
287 terminated if STR_TERMINATE isn't set. */
289 for (i
= 0; i
< (ret
/ 2) && i
< (dest_len
/ 2) && dest_ucs2
[i
]; i
++) {
290 smb_ucs2_t v
= toupper_w(dest_ucs2
[i
]);
291 if (v
!= dest_ucs2
[i
]) {
301 Copy a string from a ucs2 source to a unix char* destination.
302 Talloc version with a base pointer.
303 Uses malloc if TALLOC_CTX is NULL (this is a bad interface and
306 STR_TERMINATE means the string in src is null terminated.
307 STR_NOALIGN means don't try to align.
308 if STR_TERMINATE is set then src_len is ignored if it is -1.
309 src_len is the length of the source area in bytes
310 Return the number of bytes occupied by the string in src.
311 The resulting string in "dest" is always null terminated.
314 static size_t pull_ucs2_base_talloc(TALLOC_CTX
*ctx
,
315 const void *base_ptr
,
323 size_t ucs2_align_len
= 0;
328 /* Ensure we never use the braindead "malloc" varient. */
330 smb_panic("NULL talloc CTX in pull_ucs2_base_talloc\n");
338 if (src_len
== (size_t)-1) {
339 /* no longer used anywhere, but worth checking */
340 smb_panic("sec_len == -1 in pull_ucs2_base_talloc");
343 if (ucs2_align(base_ptr
, src
, flags
)) {
344 src
= (const void *)((const char *)src
+ 1);
349 if (flags
& STR_TERMINATE
) {
350 /* src_len -1 is the default for null terminated strings. */
351 size_t len
= strnlen_w((const smb_ucs2_t
*)src
,
357 /* Ensure we don't use an insane length from the client. */
358 if (src_len
>= 1024*1024) {
359 smb_panic("Bad src length in pull_ucs2_base_talloc\n");
363 /* ucs2 is always a multiple of 2 bytes */
366 if (!convert_string_talloc(ctx
, CH_UTF16LE
, CH_UNIX
, src
, src_len
,
367 (void *)&dest
, &dest_len
)) {
372 /* Did we already process the terminating zero ? */
373 if (dest
[dest_len
-1] != 0) {
374 size_t size
= talloc_get_size(dest
);
375 /* Have we got space to append the '\0' ? */
376 if (size
<= dest_len
) {
378 dest
= talloc_realloc(ctx
, dest
, char,
382 dest_len
= (size_t)-1;
387 dest
[dest_len
] = '\0';
395 return src_len
+ ucs2_align_len
;
399 Copy a string from a char* src to a unicode or ascii
400 dos codepage destination choosing unicode or ascii based on the
402 Return the number of bytes occupied by the string in the destination.
404 STR_TERMINATE means include the null termination.
405 STR_UPPER means uppercase in the destination.
406 STR_ASCII use ascii even with unicode packet.
407 STR_NOALIGN means don't do alignment.
408 dest_len is the maximum length allowed in the destination. If dest_len
409 is -1 then no maxiumum is used.
412 size_t push_string_check_fn(void *dest
, const char *src
,
413 size_t dest_len
, int flags
)
415 if (!(flags
& STR_ASCII
) && (flags
& STR_UNICODE
)) {
416 return push_ucs2(NULL
, dest
, src
, dest_len
, flags
);
418 return push_ascii(dest
, src
, dest_len
, flags
);
423 Copy a string from a char* src to a unicode or ascii
424 dos codepage destination choosing unicode or ascii based on the
425 flags in the SMB buffer starting at base_ptr.
426 Return the number of bytes occupied by the string in the destination.
428 STR_TERMINATE means include the null termination.
429 STR_UPPER means uppercase in the destination.
430 STR_ASCII use ascii even with unicode packet.
431 STR_NOALIGN means don't do alignment.
432 dest_len is the maximum length allowed in the destination. If dest_len
433 is -1 then no maxiumum is used.
436 size_t push_string_base(const char *base
, uint16 flags2
,
437 void *dest
, const char *src
,
438 size_t dest_len
, int flags
)
441 if (!(flags
& STR_ASCII
) && \
442 ((flags
& STR_UNICODE
|| \
443 (flags2
& FLAGS2_UNICODE_STRINGS
)))) {
444 return push_ucs2(base
, dest
, src
, dest_len
, flags
);
446 return push_ascii(dest
, src
, dest_len
, flags
);
450 Copy a string from a unicode or ascii source (depending on
451 the packet flags) to a char* destination.
452 Variant that uses talloc.
454 STR_TERMINATE means the string in src is null terminated.
455 STR_UNICODE means to force as unicode.
456 STR_ASCII use ascii even with unicode packet.
457 STR_NOALIGN means don't do alignment.
458 if STR_TERMINATE is set then src_len is ignored is it is -1
459 src_len is the length of the source area in bytes.
460 Return the number of bytes occupied by the string in src.
461 The resulting string in "dest" is always null terminated.
464 size_t pull_string_talloc(TALLOC_CTX
*ctx
,
465 const void *base_ptr
,
472 if ((base_ptr
== NULL
) && ((flags
& (STR_ASCII
|STR_UNICODE
)) == 0)) {
473 smb_panic("No base ptr to get flg2 and neither ASCII nor "
477 if (!(flags
& STR_ASCII
) && \
478 ((flags
& STR_UNICODE
|| \
479 (smb_flags2
& FLAGS2_UNICODE_STRINGS
)))) {
480 return pull_ucs2_base_talloc(ctx
,
487 return pull_ascii_base_talloc(ctx
,
495 size_t align_string(const void *base_ptr
, const char *p
, int flags
)
497 if (!(flags
& STR_ASCII
) && \
498 ((flags
& STR_UNICODE
|| \
499 (SVAL(base_ptr
, smb_flg2
) & FLAGS2_UNICODE_STRINGS
)))) {
500 return ucs2_align(base_ptr
, p
, flags
);
505 /*******************************************************************
506 Write a string in (little-endian) unicode format. src is in
507 the current DOS codepage. len is the length in bytes of the
508 string pointed to by dst.
510 if null_terminate is True then null terminate the packet (adds 2 bytes)
512 the return value is the length in bytes consumed by the string, including the
513 null termination if applied
514 ********************************************************************/
516 size_t dos_PutUniCode(char *dst
,const char *src
, size_t len
, bool null_terminate
)
518 int flags
= null_terminate
? STR_UNICODE
|STR_NOALIGN
|STR_TERMINATE
519 : STR_UNICODE
|STR_NOALIGN
;
520 return push_ucs2(NULL
, dst
, src
, len
, flags
);
524 /* Converts a string from internal samba format to unicode. Always terminates.
525 * Actually just a wrapper round push_ucs2_talloc().
528 int rpcstr_push_talloc(TALLOC_CTX
*ctx
, smb_ucs2_t
**dest
, const char *src
)
531 if (push_ucs2_talloc(ctx
, dest
, src
, &size
))