diff options
author | Jeremy Allison <jra@samba.org> | 2008-01-16 17:33:19 -0800 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2008-01-16 17:33:19 -0800 |
commit | f44713df4d636203354c55d9a9bc2538073cf0af (patch) | |
tree | 01171a1c6acf905082af9a38d4a1ff8e7caa3f70 | |
parent | 3020ec12a39276eaf3978323f4048b8a2e430bea (diff) | |
download | samba-f44713df4d636203354c55d9a9bc2538073cf0af.tar.gz samba-f44713df4d636203354c55d9a9bc2538073cf0af.tar.bz2 samba-f44713df4d636203354c55d9a9bc2538073cf0af.zip |
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)
-rw-r--r-- | source3/libsmb/clireadwrite.c | 49 |
1 files changed, 28 insertions, 21 deletions
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; + } } } |