From 6f7760704734318acb643610d1af84ffeb8c55d5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 16 Oct 2008 15:40:57 -0700 Subject: Fix bug 5826 - Directory/Filenames get truncated when 3.2.0 client acesses old server. There was some code in pull_ucs2_base_talloc() to cope with this case which hadn't been added to pull_ascii_base_talloc(). The older Samba returns non unicode names which is why you are seeing this codepath being executed. Unify the logic in pull_ascii_base_talloc() and pull_ucs2_base_talloc(). Jeremy. --- source3/lib/charcnv.c | 58 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 13 deletions(-) (limited to 'source3') 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) { -- cgit