diff options
author | Jeremy Allison <jra@samba.org> | 2008-10-16 15:40:57 -0700 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2008-10-16 15:40:57 -0700 |
commit | 6f7760704734318acb643610d1af84ffeb8c55d5 (patch) | |
tree | c8cbd2af5cc5a3980eb2537be16a0a7c61fc975f /source3 | |
parent | 2deeb99fff1a90c79ba1927e1a069362e250a63c (diff) | |
download | samba-6f7760704734318acb643610d1af84ffeb8c55d5.tar.gz samba-6f7760704734318acb643610d1af84ffeb8c55d5.tar.bz2 samba-6f7760704734318acb643610d1af84ffeb8c55d5.zip |
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.
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) { |