patch 9.0.0810: readblob() returns empty when trying to read too much

Problem:    readblob() returns empty when trying to read too much.
Solution:   Return what is available.
This commit is contained in:
Bram Moolenaar
2022-10-21 11:25:30 +01:00
parent 63c84731c1
commit 5b2a3d77d3
4 changed files with 32 additions and 13 deletions

View File

@ -6866,8 +6866,10 @@ readblob({fname} [, {offset} [, {size}]]) *readblob()*
readblob('/dev/ttyS0', 0, 10)
< When the file can't be opened an error message is given and
the result is an empty |Blob|.
When trying to read bytes beyond the end of the file the
result is an empty blob.
When the offset is beyond the end of the file the result is an
empty blob.
When trying to read more bytes than are available the result
is truncated.
Also see |readfile()| and |writefile()|.

View File

@ -199,24 +199,32 @@ read_blob(FILE *fd, typval_T *rettv, off_T offset, off_T size_arg)
if (offset >= 0)
{
if (size == -1)
// The size defaults to the whole file. If a size is given it is
// limited to not go past the end of the file.
if (size == -1 || (size > st.st_size - offset
#ifdef S_ISCHR
&& !S_ISCHR(st.st_mode)
#endif
))
// size may become negative, checked below
size = st.st_size - offset;
whence = SEEK_SET;
}
else
{
if (size == -1)
// limit the offset to not go before the start of the file
if (-offset > st.st_size
#ifdef S_ISCHR
&& !S_ISCHR(st.st_mode)
#endif
)
offset = -st.st_size;
// Size defaults to reading until the end of the file.
if (size == -1 || size > -offset)
size = -offset;
whence = SEEK_END;
}
// Trying to read bytes that aren't there results in an empty blob, not an
// error.
if (size <= 0 || (
#ifdef S_ISCHR
!S_ISCHR(st.st_mode) &&
#endif
size > st.st_size))
if (size <= 0)
return OK;
if (offset != 0 && vim_fseek(fd, offset, whence) != 0)
return OK;

View File

@ -499,10 +499,17 @@ func Test_blob_read_write()
VAR br6 = readblob('Xblob', -3, 2)
call assert_equal(b[-3 : -2], br6)
#" reading past end of file, empty result
VAR br1e = readblob('Xblob', 10000)
call assert_equal(0z, br1e)
VAR br2e = readblob('Xblob', -10000)
call assert_equal(0z, br2e)
#" reading too much, result is truncated
VAR blong = readblob('Xblob', -1000)
call assert_equal(b, blong)
LET blong = readblob('Xblob', -10, 8)
call assert_equal(b, blong)
LET blong = readblob('Xblob', 0, 10)
call assert_equal(b, blong)
call delete('Xblob')
END

View File

@ -695,6 +695,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
810,
/**/
809,
/**/