diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/lib/charcnv.c | 58 |
1 files changed, 45 insertions, 13 deletions
diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index 485212b100..3ec3220900 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -1166,7 +1166,7 @@ static size_t pull_ascii_base_talloc(TALLOC_CTX *ctx, int flags) { char *dest = NULL; - size_t converted_size; + size_t dest_len; #ifdef DEVELOPER /* Ensure we never use the braindead "malloc" varient. */ @@ -1177,6 +1177,10 @@ static size_t pull_ascii_base_talloc(TALLOC_CTX *ctx, *ppdest = NULL; + if (!src_len) { + return 0; + } + if (flags & STR_TERMINATE) { if (src_len == (size_t)-1) { src_len = strlen((const char *)src) + 1; @@ -1194,18 +1198,41 @@ static size_t pull_ascii_base_talloc(TALLOC_CTX *ctx, (unsigned int)src_len); smb_panic(msg); } + } else { + /* Can't have an unlimited length + * non STR_TERMINATE'd. + */ + if (src_len == (size_t)-1) { + errno = EINVAL; + return 0; + } } + /* src_len != -1 here. */ + if (!convert_string_allocate(ctx, CH_DOS, CH_UNIX, src, src_len, &dest, - &converted_size, True)) - { - converted_size = 0; + &dest_len, True)) { + dest_len = 0; } - if (converted_size && dest) { + if (dest_len && dest) { /* Did we already process the terminating zero ? */ - if (dest[converted_size - 1] != 0) { - dest[converted_size - 1] = 0; + if (dest[dest_len-1] != 0) { + size_t size = talloc_get_size(dest); + /* Have we got space to append the '\0' ? */ + if (size <= dest_len) { + /* No, realloc. */ + dest = TALLOC_REALLOC_ARRAY(ctx, dest, char, + dest_len+1); + if (!dest) { + /* talloc fail. */ + dest_len = (size_t)-1; + return 0; + } + } + /* Yay - space ! */ + dest[dest_len] = '\0'; + dest_len++; } } else if (dest) { dest[0] = 0; @@ -1562,21 +1589,26 @@ size_t pull_ucs2_base_talloc(TALLOC_CTX *ctx, if (src_len >= 1024*1024) { smb_panic("Bad src length in pull_ucs2_base_talloc\n"); } + } else { + /* Can't have an unlimited length + * non STR_TERMINATE'd. + */ + if (src_len == (size_t)-1) { + errno = EINVAL; + return 0; + } } + /* src_len != -1 here. */ + /* ucs2 is always a multiple of 2 bytes */ - if (src_len != (size_t)-1) { - src_len &= ~1; - } + src_len &= ~1; if (!convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, src, src_len, (void *)&dest, &dest_len, True)) { dest_len = 0; } - if (src_len == (size_t)-1) - src_len = dest_len*2; - if (dest_len) { /* Did we already process the terminating zero ? */ if (dest[dest_len-1] != 0) { |