"Bad string lengths len1=%u ofs=%u len2=%u\n",
len1, ofs, len2);
}
- if (len2 == 0) {
- *s = talloc_strdup(ndr, "");
- break;
- }
NDR_PULL_NEED_BYTES(ndr, (len2 + c_len_term)*byte_mul);
- ret = convert_string_talloc(ndr, chset, CH_UNIX,
- ndr->data+ndr->offset,
- (len2 + c_len_term)*byte_mul,
- (void **)&as);
- if (ret == -1) {
- return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
- "Bad character conversion");
+ if (len2 == 0) {
+ as = talloc_strdup(ndr->current_mem_ctx, "");
+ } else {
+ ret = convert_string_talloc(ndr->current_mem_ctx,
+ chset, CH_UNIX,
+ ndr->data+ndr->offset,
+ (len2 + c_len_term)*byte_mul,
+ (void **)&as);
+ if (ret == -1) {
+ return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
+ "Bad character conversion");
+ }
}
NDR_CHECK(ndr_pull_advance(ndr, (len2 + c_len_term)*byte_mul));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &len1));
NDR_PULL_NEED_BYTES(ndr, (len1 + c_len_term)*byte_mul);
if (len1 == 0) {
- *s = talloc_strdup(ndr, "");
- break;
- }
- ret = convert_string_talloc(ndr, chset, CH_UNIX,
- ndr->data+ndr->offset,
- (len1 + c_len_term)*byte_mul,
- (void **)&as);
- if (ret == -1) {
- return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
- "Bad character conversion");
+ as = talloc_strdup(ndr->current_mem_ctx, "");
+ } else {
+ ret = convert_string_talloc(ndr->current_mem_ctx,
+ chset, CH_UNIX,
+ ndr->data+ndr->offset,
+ (len1 + c_len_term)*byte_mul,
+ (void **)&as);
+ if (ret == -1) {
+ return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
+ "Bad character conversion");
+ }
}
NDR_CHECK(ndr_pull_advance(ndr, (len1 + c_len_term)*byte_mul));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &len1));
NDR_PULL_NEED_BYTES(ndr, (len1 + c_len_term)*byte_mul);
if (len1 == 0) {
- *s = talloc_strdup(ndr, "");
- break;
- }
- ret = convert_string_talloc(ndr, chset, CH_UNIX,
- ndr->data+ndr->offset,
- (len1 + c_len_term)*byte_mul,
- (void **)&as);
- if (ret == -1) {
- return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
- "Bad character conversion");
+ as = talloc_strdup(ndr->current_mem_ctx, "");
+ } else {
+ ret = convert_string_talloc(ndr->current_mem_ctx,
+ chset, CH_UNIX,
+ ndr->data+ndr->offset,
+ (len1 + c_len_term)*byte_mul,
+ (void **)&as);
+ if (ret == -1) {
+ return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
+ "Bad character conversion");
+ }
}
NDR_CHECK(ndr_pull_advance(ndr, (len1 + c_len_term)*byte_mul));
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &len3));
NDR_PULL_NEED_BYTES(ndr, (len3 + c_len_term)*byte_mul);
if (len3 == 0) {
- *s = talloc_strdup(ndr, "");
- break;
- }
- ret = convert_string_talloc(ndr, chset, CH_UNIX,
- ndr->data+ndr->offset,
- (len3 + c_len_term)*byte_mul,
- (void **)&as);
- if (ret == -1) {
- return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
- "Bad character conversion");
+ as = talloc_strdup(ndr->current_mem_ctx, "");
+ } else {
+ ret = convert_string_talloc(ndr->current_mem_ctx,
+ chset, CH_UNIX,
+ ndr->data+ndr->offset,
+ (len3 + c_len_term)*byte_mul,
+ (void **)&as);
+ if (ret == -1) {
+ return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
+ "Bad character conversion");
+ }
}
NDR_CHECK(ndr_pull_advance(ndr, (len3 + c_len_term)*byte_mul));
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &len3));
NDR_PULL_NEED_BYTES(ndr, len3);
if (len3 == 0) {
- *s = talloc_strdup(ndr, "");
- break;
- }
- ret = convert_string_talloc(ndr, chset, CH_UNIX,
- ndr->data+ndr->offset,
- len3,
- (void **)&as);
- if (ret == -1) {
- return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
- "Bad character conversion");
+ as = talloc_strdup(ndr->current_mem_ctx, "");
+ } else {
+ ret = convert_string_talloc(ndr->current_mem_ctx,
+ chset, CH_UNIX,
+ ndr->data+ndr->offset,
+ len3,
+ (void **)&as);
+ if (ret == -1) {
+ return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
+ "Bad character conversion");
+ }
}
NDR_CHECK(ndr_pull_advance(ndr, len3));
*s = as;
} else {
len1 = utf16_len_n(ndr->data+ndr->offset, ndr->data_size - ndr->offset);
}
- ret = convert_string_talloc(ndr, chset, CH_UNIX,
+ ret = convert_string_talloc(ndr->current_mem_ctx,
+ chset, CH_UNIX,
ndr->data+ndr->offset,
len1,
(void **)&as);
case LIBNDR_FLAG_STR_FIXLEN32:
len1 = (flags & LIBNDR_FLAG_STR_FIXLEN32)?32:15;
NDR_PULL_NEED_BYTES(ndr, len1*byte_mul);
- ret = convert_string_talloc(ndr, chset, CH_UNIX,
+ ret = convert_string_talloc(ndr->current_mem_ctx,
+ chset, CH_UNIX,
ndr->data+ndr->offset,
len1*byte_mul,
(void **)&as);
}
for (count = 0;; count++) {
+ TALLOC_CTX *tmp_ctx;
const char *s = NULL;
- a = talloc_realloc(ndr, a, const char *, count + 2);
+ a = talloc_realloc(ndr->current_mem_ctx, a, const char *, count + 2);
NT_STATUS_HAVE_NO_MEMORY(a);
a[count] = NULL;
a[count+1] = NULL;
+ tmp_ctx = ndr->current_mem_ctx;
+ ndr->current_mem_ctx = a;
NDR_CHECK(ndr_pull_string(ndr, ndr_flags, &s));
+ ndr->current_mem_ctx = tmp_ctx;
if (strcmp("", s)==0) {
a[count] = NULL;
break;
}
/* Return number of elements in a string including the last (zeroed) element */
-uint32_t ndr_string_length(void *_var, uint32_t element_size)
+uint32_t ndr_string_length(const void *_var, uint32_t element_size)
{
uint32_t i;
uint8_t zero[4] = {0,0,0,0};
- char *var = _var;
+ const char *var = _var;
for (i = 0; memcmp(var+i*element_size,zero,element_size) != 0; i++);
return i+1;
}
-NTSTATUS ndr_check_string_terminator(struct ndr_pull *ndr, const void *_var, uint32_t count, uint32_t element_size)
+NTSTATUS ndr_check_string_terminator(struct ndr_pull *ndr, uint32_t count, uint32_t element_size)
{
- const char *var = _var;
uint32_t i;
+ struct ndr_pull_save save_offset;
- var += element_size*(count-1);
+ ndr_pull_save(ndr, &save_offset);
+ ndr_pull_advance(ndr, (count - 1) * element_size);
+ NDR_PULL_NEED_BYTES(ndr, element_size);
for (i = 0; i < element_size; i++) {
- if (var[i] != 0) {
- return NT_STATUS_UNSUCCESSFUL;
+ if (ndr->data[ndr->offset+i] != 0) {
+ ndr_pull_restore(ndr, &save_offset);
+
+ return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "String terminator not present or outside string boundaries");
}
}
- return NT_STATUS_OK;
+ ndr_pull_restore(ndr, &save_offset);
+ return NT_STATUS_OK;
}
-NTSTATUS ndr_pull_charset(struct ndr_pull *ndr, int ndr_flags, char **var, uint32_t length, uint8_t byte_mul, int chset)
+NTSTATUS ndr_pull_charset(struct ndr_pull *ndr, int ndr_flags, const char **var, uint32_t length, uint8_t byte_mul, int chset)
{
int ret;
+ if (length == 0) {
+ *var = talloc_strdup(ndr->current_mem_ctx, "");
+ return NT_STATUS_OK;
+ }
+
NDR_PULL_NEED_BYTES(ndr, length*byte_mul);
- ret = convert_string_talloc(ndr, chset, CH_UNIX,
+
+ if (ndr->flags & LIBNDR_FLAG_STR_NULLTERM) {
+ /* Explicitly ignore the return value here. An array that
+ * is not zero-terminated is considered a warning only, not fatal */
+ ndr_check_string_terminator(ndr, length, byte_mul);
+ }
+
+ ret = convert_string_talloc(ndr->current_mem_ctx,
+ chset, CH_UNIX,
ndr->data+ndr->offset,
length*byte_mul,
- (void **)var);
+ discard_const_p(void *, var));
if (ret == -1) {
return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
"Bad character conversion");
NTSTATUS ndr_push_charset(struct ndr_push *ndr, int ndr_flags, const char *var, uint32_t length, uint8_t byte_mul, int chset)
{
- ssize_t ret;
- NDR_PUSH_NEED_BYTES(ndr, byte_mul*length);
+ ssize_t ret, required;
+
+ required = byte_mul * length;
+
+ NDR_PUSH_NEED_BYTES(ndr, required);
ret = convert_string(CH_UNIX, chset,
- var, length,
- ndr->data+ndr->offset, byte_mul*length);
+ var, strlen(var),
+ ndr->data+ndr->offset, required);
if (ret == -1) {
return ndr_push_error(ndr, NDR_ERR_CHARCNV,
"Bad character conversion");
}
- ndr->offset += ret;
+
+ /* Make sure the remaining part of the string is filled with zeroes */
+ if (ret < required) {
+ memset(ndr->data+ndr->offset+ret, 0, required-ret);
+ }
+
+ ndr->offset += required;
return NT_STATUS_OK;
}
+
+/* Return number of elements in a string in the specified charset */
+uint32_t ndr_charset_length(const void *var, int chset)
+{
+ /* FIXME: Treat special chars special here, taking chset into account */
+ /* Also include 0 byte */
+ return strlen(var)+1;
+}