2 Unix SMB/CIFS implementation.
4 routines for marshalling/unmarshalling string types
6 Copyright (C) Andrew Tridgell 2003
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "librpc/ndr/libndr.h"
26 pull a general string from the wire
28 _PUBLIC_
enum ndr_err_code
ndr_pull_string(struct ndr_pull
*ndr
, int ndr_flags
, const char **s
)
31 uint32_t len1
, ofs
, len2
;
33 size_t converted_size
;
35 unsigned byte_mul
= 2;
36 unsigned flags
= ndr
->flags
;
37 unsigned c_len_term
= 0;
39 if (!(ndr_flags
& NDR_SCALARS
)) {
40 return NDR_ERR_SUCCESS
;
47 if (flags
& LIBNDR_FLAG_STR_ASCII
) {
50 flags
&= ~LIBNDR_FLAG_STR_ASCII
;
53 if (flags
& LIBNDR_FLAG_STR_UTF8
) {
56 flags
&= ~LIBNDR_FLAG_STR_UTF8
;
59 flags
&= ~LIBNDR_FLAG_STR_CONFORMANT
;
60 if (flags
& LIBNDR_FLAG_STR_CHARLEN
) {
62 flags
&= ~LIBNDR_FLAG_STR_CHARLEN
;
65 switch (flags
& LIBNDR_STRING_FLAGS
) {
66 case LIBNDR_FLAG_STR_LEN4
|LIBNDR_FLAG_STR_SIZE4
:
67 case LIBNDR_FLAG_STR_LEN4
|LIBNDR_FLAG_STR_SIZE4
|LIBNDR_FLAG_STR_NOTERM
:
68 NDR_CHECK(ndr_pull_uint32(ndr
, NDR_SCALARS
, &len1
));
69 NDR_CHECK(ndr_pull_uint32(ndr
, NDR_SCALARS
, &ofs
));
71 return ndr_pull_error(ndr
, NDR_ERR_STRING
, "non-zero array offset with string flags 0x%x\n",
72 ndr
->flags
& LIBNDR_STRING_FLAGS
);
74 NDR_CHECK(ndr_pull_uint32(ndr
, NDR_SCALARS
, &len2
));
76 return ndr_pull_error(ndr
, NDR_ERR_STRING
,
77 "Bad string lengths len1=%u ofs=%u len2=%u\n",
80 NDR_PULL_NEED_BYTES(ndr
, (len2
+ c_len_term
)*byte_mul
);
82 as
= talloc_strdup(ndr
->current_mem_ctx
, "");
84 if (!convert_string_talloc(ndr
->current_mem_ctx
, chset
,
86 ndr
->data
+ndr
->offset
,
87 (len2
+ c_len_term
)*byte_mul
,
89 &converted_size
, false))
91 return ndr_pull_error(ndr
, NDR_ERR_CHARCNV
,
92 "Bad char conversion");
95 NDR_CHECK(ndr_pull_advance(ndr
, (len2
+ c_len_term
)*byte_mul
));
98 DEBUG(6,("len1[%u] != len2[%u] '%s'\n", len1
, len2
, as
));
101 /* this is a way of detecting if a string is sent with the wrong
103 if (ndr
->flags
& LIBNDR_FLAG_STR_NOTERM
) {
104 if (strlen(as
) < (len2
+ c_len_term
)) {
105 DEBUG(6,("short string '%s'\n", as
));
108 if (strlen(as
) == (len2
+ c_len_term
)) {
109 DEBUG(6,("long string '%s'\n", as
));
115 case LIBNDR_FLAG_STR_SIZE4
:
116 case LIBNDR_FLAG_STR_SIZE4
|LIBNDR_FLAG_STR_NOTERM
:
117 NDR_CHECK(ndr_pull_uint32(ndr
, NDR_SCALARS
, &len1
));
118 NDR_PULL_NEED_BYTES(ndr
, (len1
+ c_len_term
)*byte_mul
);
120 as
= talloc_strdup(ndr
->current_mem_ctx
, "");
122 if (!convert_string_talloc(ndr
->current_mem_ctx
, chset
,
124 ndr
->data
+ndr
->offset
,
125 (len1
+ c_len_term
)*byte_mul
,
126 (void **)(void *)&as
,
127 &converted_size
, false))
129 return ndr_pull_error(ndr
, NDR_ERR_CHARCNV
,
130 "Bad char conversion");
133 NDR_CHECK(ndr_pull_advance(ndr
, (len1
+ c_len_term
)*byte_mul
));
135 /* this is a way of detecting if a string is sent with the wrong
137 if (ndr
->flags
& LIBNDR_FLAG_STR_NOTERM
) {
138 if (strlen(as
) < (len1
+ c_len_term
)) {
139 DEBUG(6,("short string '%s'\n", as
));
142 if (strlen(as
) == (len1
+ c_len_term
)) {
143 DEBUG(6,("long string '%s'\n", as
));
149 case LIBNDR_FLAG_STR_LEN4
:
150 case LIBNDR_FLAG_STR_LEN4
|LIBNDR_FLAG_STR_NOTERM
:
151 NDR_CHECK(ndr_pull_uint32(ndr
, NDR_SCALARS
, &ofs
));
153 return ndr_pull_error(ndr
, NDR_ERR_STRING
, "non-zero array offset with string flags 0x%x\n",
154 ndr
->flags
& LIBNDR_STRING_FLAGS
);
156 NDR_CHECK(ndr_pull_uint32(ndr
, NDR_SCALARS
, &len1
));
157 NDR_PULL_NEED_BYTES(ndr
, (len1
+ c_len_term
)*byte_mul
);
159 as
= talloc_strdup(ndr
->current_mem_ctx
, "");
161 if (!convert_string_talloc(ndr
->current_mem_ctx
, chset
,
163 ndr
->data
+ndr
->offset
,
164 (len1
+ c_len_term
)*byte_mul
,
165 (void **)(void *)&as
,
166 &converted_size
, false))
168 return ndr_pull_error(ndr
, NDR_ERR_CHARCNV
,
169 "Bad char conversion");
172 NDR_CHECK(ndr_pull_advance(ndr
, (len1
+ c_len_term
)*byte_mul
));
174 /* this is a way of detecting if a string is sent with the wrong
176 if (ndr
->flags
& LIBNDR_FLAG_STR_NOTERM
) {
177 if (strlen(as
) < (len1
+ c_len_term
)) {
178 DEBUG(6,("short string '%s'\n", as
));
181 if (strlen(as
) == (len1
+ c_len_term
)) {
182 DEBUG(6,("long string '%s'\n", as
));
189 case LIBNDR_FLAG_STR_SIZE2
:
190 case LIBNDR_FLAG_STR_SIZE2
|LIBNDR_FLAG_STR_NOTERM
:
191 NDR_CHECK(ndr_pull_uint16(ndr
, NDR_SCALARS
, &len3
));
192 NDR_PULL_NEED_BYTES(ndr
, (len3
+ c_len_term
)*byte_mul
);
194 as
= talloc_strdup(ndr
->current_mem_ctx
, "");
196 if (!convert_string_talloc(ndr
->current_mem_ctx
, chset
,
198 ndr
->data
+ndr
->offset
,
199 (len3
+ c_len_term
)*byte_mul
,
200 (void **)(void *)&as
,
201 &converted_size
, false))
203 return ndr_pull_error(ndr
, NDR_ERR_CHARCNV
,
204 "Bad char conversion");
207 NDR_CHECK(ndr_pull_advance(ndr
, (len3
+ c_len_term
)*byte_mul
));
209 /* this is a way of detecting if a string is sent with the wrong
211 if (ndr
->flags
& LIBNDR_FLAG_STR_NOTERM
) {
212 if (strlen(as
) < (len3
+ c_len_term
)) {
213 DEBUG(6,("short string '%s'\n", as
));
216 if (strlen(as
) == (len3
+ c_len_term
)) {
217 DEBUG(6,("long string '%s'\n", as
));
223 case LIBNDR_FLAG_STR_SIZE2
|LIBNDR_FLAG_STR_NOTERM
|LIBNDR_FLAG_STR_BYTESIZE
:
224 NDR_CHECK(ndr_pull_uint16(ndr
, NDR_SCALARS
, &len3
));
225 NDR_PULL_NEED_BYTES(ndr
, len3
);
227 as
= talloc_strdup(ndr
->current_mem_ctx
, "");
229 if (!convert_string_talloc(ndr
->current_mem_ctx
, chset
,
231 ndr
->data
+ndr
->offset
, len3
,
232 (void **)(void *)&as
,
233 &converted_size
, false))
235 return ndr_pull_error(ndr
, NDR_ERR_CHARCNV
,
236 "Bad char conversion");
239 NDR_CHECK(ndr_pull_advance(ndr
, len3
));
243 case LIBNDR_FLAG_STR_NULLTERM
:
245 len1
= ascii_len_n((const char *)(ndr
->data
+ndr
->offset
), ndr
->data_size
- ndr
->offset
);
247 len1
= utf16_len_n(ndr
->data
+ndr
->offset
, ndr
->data_size
- ndr
->offset
);
249 if (!convert_string_talloc(ndr
->current_mem_ctx
, chset
, CH_UNIX
,
250 ndr
->data
+ndr
->offset
, len1
,
251 (void **)(void *)&as
,
252 &converted_size
, false))
254 return ndr_pull_error(ndr
, NDR_ERR_CHARCNV
,
255 "Bad char conversion");
257 NDR_CHECK(ndr_pull_advance(ndr
, len1
));
261 case LIBNDR_FLAG_STR_FIXLEN15
:
262 case LIBNDR_FLAG_STR_FIXLEN32
:
263 len1
= (flags
& LIBNDR_FLAG_STR_FIXLEN32
)?32:15;
264 NDR_PULL_NEED_BYTES(ndr
, len1
*byte_mul
);
265 if (!convert_string_talloc(ndr
->current_mem_ctx
, chset
, CH_UNIX
,
266 ndr
->data
+ndr
->offset
, len1
*byte_mul
,
267 (void **)(void *)&as
,
268 &converted_size
, false))
270 return ndr_pull_error(ndr
, NDR_ERR_CHARCNV
,
271 "Bad char conversion");
273 NDR_CHECK(ndr_pull_advance(ndr
, len1
*byte_mul
));
277 case LIBNDR_FLAG_STR_NOTERM
:
278 if (!(ndr
->flags
& LIBNDR_FLAG_REMAINING
)) {
279 return ndr_pull_error(ndr
, NDR_ERR_STRING
, "Bad string flags 0x%x (missing NDR_REMAINING)\n",
280 ndr
->flags
& LIBNDR_STRING_FLAGS
);
283 len1
= ndr
->data_size
- ndr
->offset
;
285 NDR_PULL_NEED_BYTES(ndr
, len1
);
287 as
= talloc_strdup(ndr
->current_mem_ctx
, "");
289 if (!convert_string_talloc(ndr
->current_mem_ctx
, chset
,
291 ndr
->data
+ndr
->offset
, len1
,
292 (void **)(void *)&as
,
293 &converted_size
, false))
295 return ndr_pull_error(ndr
, NDR_ERR_CHARCNV
,
296 "Bad char conversion");
299 NDR_CHECK(ndr_pull_advance(ndr
, len1
));
305 return ndr_pull_error(ndr
, NDR_ERR_STRING
, "Bad string flags 0x%x\n",
306 ndr
->flags
& LIBNDR_STRING_FLAGS
);
309 return NDR_ERR_SUCCESS
;
314 push a general string onto the wire
316 _PUBLIC_
enum ndr_err_code
ndr_push_string(struct ndr_push
*ndr
, int ndr_flags
, const char *s
)
318 ssize_t s_len
, c_len
;
320 int chset
= CH_UTF16
;
321 unsigned flags
= ndr
->flags
;
322 unsigned byte_mul
= 2;
323 uint8_t *dest
= NULL
;
325 if (!(ndr_flags
& NDR_SCALARS
)) {
326 return NDR_ERR_SUCCESS
;
333 s_len
= s
?strlen(s
):0;
335 if (flags
& LIBNDR_FLAG_STR_ASCII
) {
338 flags
&= ~LIBNDR_FLAG_STR_ASCII
;
341 if (flags
& LIBNDR_FLAG_STR_UTF8
) {
344 flags
&= ~LIBNDR_FLAG_STR_UTF8
;
347 flags
&= ~LIBNDR_FLAG_STR_CONFORMANT
;
350 (LIBNDR_FLAG_STR_NOTERM
|
351 LIBNDR_FLAG_STR_FIXLEN15
|
352 LIBNDR_FLAG_STR_FIXLEN32
))) {
355 if (!convert_string_talloc(ndr
, CH_UNIX
, chset
, s
, s_len
,
356 (void **)(void *)&dest
, &d_len
, false))
358 return ndr_push_error(ndr
, NDR_ERR_CHARCNV
,
359 "Bad char conversion");
362 if (flags
& LIBNDR_FLAG_STR_BYTESIZE
) {
364 flags
&= ~LIBNDR_FLAG_STR_BYTESIZE
;
365 } else if (flags
& LIBNDR_FLAG_STR_CHARLEN
) {
366 c_len
= (d_len
/ byte_mul
)-1;
367 flags
&= ~LIBNDR_FLAG_STR_CHARLEN
;
369 c_len
= d_len
/ byte_mul
;
372 switch ((flags
& LIBNDR_STRING_FLAGS
) & ~LIBNDR_FLAG_STR_NOTERM
) {
373 case LIBNDR_FLAG_STR_LEN4
|LIBNDR_FLAG_STR_SIZE4
:
374 NDR_CHECK(ndr_push_uint32(ndr
, NDR_SCALARS
, c_len
));
375 NDR_CHECK(ndr_push_uint32(ndr
, NDR_SCALARS
, 0));
376 NDR_CHECK(ndr_push_uint32(ndr
, NDR_SCALARS
, c_len
));
377 NDR_CHECK(ndr_push_bytes(ndr
, dest
, d_len
));
380 case LIBNDR_FLAG_STR_LEN4
:
381 NDR_CHECK(ndr_push_uint32(ndr
, NDR_SCALARS
, 0));
382 NDR_CHECK(ndr_push_uint32(ndr
, NDR_SCALARS
, c_len
));
383 NDR_CHECK(ndr_push_bytes(ndr
, dest
, d_len
));
386 case LIBNDR_FLAG_STR_SIZE4
:
387 NDR_CHECK(ndr_push_uint32(ndr
, NDR_SCALARS
, c_len
));
388 NDR_CHECK(ndr_push_bytes(ndr
, dest
, d_len
));
391 case LIBNDR_FLAG_STR_SIZE2
:
392 NDR_CHECK(ndr_push_uint16(ndr
, NDR_SCALARS
, c_len
));
393 NDR_CHECK(ndr_push_bytes(ndr
, dest
, d_len
));
396 case LIBNDR_FLAG_STR_NULLTERM
:
397 NDR_CHECK(ndr_push_bytes(ndr
, dest
, d_len
));
400 case LIBNDR_FLAG_STR_FIXLEN15
:
401 case LIBNDR_FLAG_STR_FIXLEN32
: {
402 ssize_t fix_len
= (flags
& LIBNDR_FLAG_STR_FIXLEN32
)?32:15;
403 uint32_t pad_len
= fix_len
- d_len
;
404 if (d_len
> fix_len
) {
405 return ndr_push_error(ndr
, NDR_ERR_CHARCNV
,
406 "Bad char conversion");
408 NDR_CHECK(ndr_push_bytes(ndr
, dest
, d_len
));
410 NDR_CHECK(ndr_push_zero(ndr
, pad_len
));
416 if (ndr
->flags
& LIBNDR_FLAG_REMAINING
) {
417 NDR_CHECK(ndr_push_bytes(ndr
, dest
, d_len
));
421 return ndr_push_error(ndr
, NDR_ERR_STRING
, "Bad string flags 0x%x\n",
422 ndr
->flags
& LIBNDR_STRING_FLAGS
);
427 return NDR_ERR_SUCCESS
;
431 push a general string onto the wire
433 _PUBLIC_
size_t ndr_string_array_size(struct ndr_push
*ndr
, const char *s
)
436 unsigned flags
= ndr
->flags
;
437 unsigned byte_mul
= 2;
438 unsigned c_len_term
= 1;
440 if (flags
& LIBNDR_FLAG_STR_FIXLEN32
) {
443 if (flags
& LIBNDR_FLAG_STR_FIXLEN15
) {
447 c_len
= s
?strlen_m(s
):0;
449 if (flags
& (LIBNDR_FLAG_STR_ASCII
|LIBNDR_FLAG_STR_UTF8
)) {
453 if (flags
& LIBNDR_FLAG_STR_NOTERM
) {
457 c_len
= c_len
+ c_len_term
;
459 if (flags
& LIBNDR_FLAG_STR_BYTESIZE
) {
460 c_len
= c_len
* byte_mul
;
466 _PUBLIC_
void ndr_print_string(struct ndr_print
*ndr
, const char *name
, const char *s
)
469 ndr
->print(ndr
, "%-25s: '%s'", name
, s
);
471 ndr
->print(ndr
, "%-25s: NULL", name
);
475 _PUBLIC_
uint32_t ndr_size_string(int ret
, const char * const* string
, int flags
)
477 /* FIXME: Is this correct for all strings ? */
478 if(!(*string
)) return ret
;
479 return ret
+strlen(*string
)+1;
483 pull a general string array from the wire
485 _PUBLIC_
enum ndr_err_code
ndr_pull_string_array(struct ndr_pull
*ndr
, int ndr_flags
, const char ***_a
)
487 const char **a
= *_a
;
489 unsigned flags
= ndr
->flags
;
490 unsigned saved_flags
= ndr
->flags
;
492 if (!(ndr_flags
& NDR_SCALARS
)) {
493 return NDR_ERR_SUCCESS
;
496 switch (flags
& LIBNDR_STRING_FLAGS
) {
497 case LIBNDR_FLAG_STR_NULLTERM
:
499 * here the strings are null terminated
500 * but also the array is null terminated
502 for (count
= 0;; count
++) {
504 const char *s
= NULL
;
505 a
= talloc_realloc(ndr
->current_mem_ctx
, a
, const char *, count
+ 2);
506 NDR_ERR_HAVE_NO_MEMORY(a
);
510 tmp_ctx
= ndr
->current_mem_ctx
;
511 ndr
->current_mem_ctx
= a
;
512 NDR_CHECK(ndr_pull_string(ndr
, ndr_flags
, &s
));
513 ndr
->current_mem_ctx
= tmp_ctx
;
514 if (strcmp("", s
)==0) {
525 case LIBNDR_FLAG_STR_NOTERM
:
526 if (!(ndr
->flags
& LIBNDR_FLAG_REMAINING
)) {
527 return ndr_pull_error(ndr
, NDR_ERR_STRING
, "Bad string flags 0x%x (missing NDR_REMAINING)\n",
528 ndr
->flags
& LIBNDR_STRING_FLAGS
);
531 * here the strings are not null terminated
532 * but serarated by a null terminator
534 * which means the same as:
535 * very string is null terminated exept the last
536 * string is terminated by the end of the buffer
538 * as LIBNDR_FLAG_STR_NULLTERM also end at the end
539 * of the buffer, we can pull each string with this flag
541 ndr
->flags
&= ~(LIBNDR_FLAG_STR_NOTERM
|LIBNDR_FLAG_REMAINING
);
542 ndr
->flags
|= LIBNDR_FLAG_STR_NULLTERM
;
544 for (count
= 0; ((ndr
->data_size
- ndr
->offset
) > 0); count
++) {
546 const char *s
= NULL
;
547 a
= talloc_realloc(ndr
->current_mem_ctx
, a
, const char *, count
+ 2);
548 NDR_ERR_HAVE_NO_MEMORY(a
);
552 tmp_ctx
= ndr
->current_mem_ctx
;
553 ndr
->current_mem_ctx
= a
;
554 NDR_CHECK(ndr_pull_string(ndr
, ndr_flags
, &s
));
555 ndr
->current_mem_ctx
= tmp_ctx
;
563 return ndr_pull_error(ndr
, NDR_ERR_STRING
, "Bad string flags 0x%x\n",
564 ndr
->flags
& LIBNDR_STRING_FLAGS
);
567 ndr
->flags
= saved_flags
;
568 return NDR_ERR_SUCCESS
;
572 push a general string array onto the wire
574 _PUBLIC_
enum ndr_err_code
ndr_push_string_array(struct ndr_push
*ndr
, int ndr_flags
, const char **a
)
577 unsigned flags
= ndr
->flags
;
578 unsigned saved_flags
= ndr
->flags
;
580 if (!(ndr_flags
& NDR_SCALARS
)) {
581 return NDR_ERR_SUCCESS
;
584 switch (flags
& LIBNDR_STRING_FLAGS
) {
585 case LIBNDR_FLAG_STR_NULLTERM
:
586 for (count
= 0; a
&& a
[count
]; count
++) {
587 NDR_CHECK(ndr_push_string(ndr
, ndr_flags
, a
[count
]));
590 NDR_CHECK(ndr_push_string(ndr
, ndr_flags
, ""));
593 case LIBNDR_FLAG_STR_NOTERM
:
594 if (!(ndr
->flags
& LIBNDR_FLAG_REMAINING
)) {
595 return ndr_push_error(ndr
, NDR_ERR_STRING
, "Bad string flags 0x%x (missing NDR_REMAINING)\n",
596 ndr
->flags
& LIBNDR_STRING_FLAGS
);
599 for (count
= 0; a
&& a
[count
]; count
++) {
601 ndr
->flags
&= ~(LIBNDR_FLAG_STR_NOTERM
|LIBNDR_FLAG_REMAINING
);
602 ndr
->flags
|= LIBNDR_FLAG_STR_NULLTERM
;
603 NDR_CHECK(ndr_push_string(ndr
, ndr_flags
, ""));
604 ndr
->flags
= saved_flags
;
606 NDR_CHECK(ndr_push_string(ndr
, ndr_flags
, a
[count
]));
612 return ndr_push_error(ndr
, NDR_ERR_STRING
, "Bad string flags 0x%x\n",
613 ndr
->flags
& LIBNDR_STRING_FLAGS
);
616 ndr
->flags
= saved_flags
;
617 return NDR_ERR_SUCCESS
;
620 _PUBLIC_
void ndr_print_string_array(struct ndr_print
*ndr
, const char *name
, const char **a
)
625 for (count
= 0; a
&& a
[count
]; count
++) {}
627 ndr
->print(ndr
, "%s: ARRAY(%d)", name
, count
);
629 for (i
=0;i
<count
;i
++) {
631 if (asprintf(&idx
, "[%d]", i
) != -1) {
632 ndr_print_string(ndr
, idx
, a
[i
]);
640 * Return number of elements in a string including the last (zeroed) element
642 _PUBLIC_
uint32_t ndr_string_length(const void *_var
, uint32_t element_size
)
645 uint8_t zero
[4] = {0,0,0,0};
646 const char *var
= (const char *)_var
;
648 for (i
= 0; memcmp(var
+i
*element_size
,zero
,element_size
) != 0; i
++);
653 _PUBLIC_
enum ndr_err_code
ndr_check_string_terminator(struct ndr_pull
*ndr
, uint32_t count
, uint32_t element_size
)
656 struct ndr_pull_save save_offset
;
658 ndr_pull_save(ndr
, &save_offset
);
659 ndr_pull_advance(ndr
, (count
- 1) * element_size
);
660 NDR_PULL_NEED_BYTES(ndr
, element_size
);
662 for (i
= 0; i
< element_size
; i
++) {
663 if (ndr
->data
[ndr
->offset
+i
] != 0) {
664 ndr_pull_restore(ndr
, &save_offset
);
666 return ndr_pull_error(ndr
, NDR_ERR_ARRAY_SIZE
, "String terminator not present or outside string boundaries");
670 ndr_pull_restore(ndr
, &save_offset
);
672 return NDR_ERR_SUCCESS
;
675 _PUBLIC_
enum ndr_err_code
ndr_pull_charset(struct ndr_pull
*ndr
, int ndr_flags
, const char **var
, uint32_t length
, uint8_t byte_mul
, charset_t chset
)
677 size_t converted_size
;
680 *var
= talloc_strdup(ndr
->current_mem_ctx
, "");
681 return NDR_ERR_SUCCESS
;
684 if (NDR_BE(ndr
) && chset
== CH_UTF16
) {
688 NDR_PULL_NEED_BYTES(ndr
, length
*byte_mul
);
690 if (!convert_string_talloc(ndr
->current_mem_ctx
, chset
, CH_UNIX
,
691 ndr
->data
+ndr
->offset
, length
*byte_mul
,
692 discard_const_p(void *, var
),
693 &converted_size
, false))
695 return ndr_pull_error(ndr
, NDR_ERR_CHARCNV
,
696 "Bad char conversion");
698 NDR_CHECK(ndr_pull_advance(ndr
, length
*byte_mul
));
700 return NDR_ERR_SUCCESS
;
703 _PUBLIC_
enum ndr_err_code
ndr_push_charset(struct ndr_push
*ndr
, int ndr_flags
, const char *var
, uint32_t length
, uint8_t byte_mul
, charset_t chset
)
705 ssize_t ret
, required
;
707 if (NDR_BE(ndr
) && chset
== CH_UTF16
) {
711 required
= byte_mul
* length
;
713 NDR_PUSH_NEED_BYTES(ndr
, required
);
714 ret
= convert_string(CH_UNIX
, chset
,
716 ndr
->data
+ndr
->offset
, required
, false);
718 return ndr_push_error(ndr
, NDR_ERR_CHARCNV
,
719 "Bad char conversion");
722 /* Make sure the remaining part of the string is filled with zeroes */
723 if (ret
< required
) {
724 memset(ndr
->data
+ndr
->offset
+ret
, 0, required
-ret
);
727 ndr
->offset
+= required
;
729 return NDR_ERR_SUCCESS
;
732 /* Return number of elements in a string in the specified charset */
733 _PUBLIC_
uint32_t ndr_charset_length(const void *var
, charset_t chset
)
735 /* FIXME: Treat special chars special here, taking chset into account */
736 /* Also include 0 byte */
737 return strlen((const char *)var
)+1;