From f44713df4d636203354c55d9a9bc2538073cf0af Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 Jan 2008 17:33:19 -0800 Subject: Fix bug found by Derrell - windows returns an read return offset of zero if return size is zero. Should fix testread libsmbclient code. Jeremy. (This used to be commit df3c4648399f8d62ff6fe0013be8b89abc18f0f0) --- source3/libsmb/clireadwrite.c | 49 ++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 21 deletions(-) (limited to 'source3/libsmb/clireadwrite.c') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 6b39a885f0..af13ed8f73 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -134,6 +134,8 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ return -1; } + /* size2 is the number of bytes the server returned. + * Might be zero. */ size2 = SVAL(cli->inbuf, smb_vwv5); size2 |= (((unsigned int)(SVAL(cli->inbuf, smb_vwv7))) << 16); @@ -145,27 +147,32 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ return -1; } - if (!direct_reads) { - /* Copy data into buffer */ - p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); - memcpy(buf + total, p, size2); - } else { - /* Ensure the remaining data matches the return size. */ - ssize_t toread = smb_len_large(cli->inbuf) - SVAL(cli->inbuf,smb_vwv6); - - /* Ensure the size is correct. */ - if (toread != size2) { - DEBUG(5,("direct read logic fail toread (%d) != size2 (%u)\n", - (int)toread, (unsigned int)size2 )); - return -1; - } - - /* Read data directly into buffer */ - toread = cli_receive_smb_data(cli,buf+total,size2); - if (toread != size2) { - DEBUG(5,("direct read read failure toread (%d) != size2 (%u)\n", - (int)toread, (unsigned int)size2 )); - return -1; + if (size2) { + /* smb_vwv6 is the offset in the packet of the returned + * data bytes. Only valid if size2 != 0. */ + + if (!direct_reads) { + /* Copy data into buffer */ + p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); + memcpy(buf + total, p, size2); + } else { + /* Ensure the remaining data matches the return size. */ + ssize_t toread = smb_len_large(cli->inbuf) - SVAL(cli->inbuf,smb_vwv6); + + /* Ensure the size is correct. */ + if (toread != size2) { + DEBUG(5,("direct read logic fail toread (%d) != size2 (%u)\n", + (int)toread, (unsigned int)size2 )); + return -1; + } + + /* Read data directly into buffer */ + toread = cli_receive_smb_data(cli,buf+total,size2); + if (toread != size2) { + DEBUG(5,("direct read read failure toread (%d) != size2 (%u)\n", + (int)toread, (unsigned int)size2 )); + return -1; + } } } -- cgit