vim-patch:9.0.0795: readblob() always reads the whole file

Problem:    readblob() always reads the whole file.
Solution:   Add arguments to read part of the file. (Ken Takata,
            closes vim/vim#11402)

11df3aeee5

Remove trailing whitespace in test as done in patch 9.0.1257.
Move the help for rand() before range().

Co-authored-by: K.Takata <kentkt@csc.jp>
This commit is contained in:
zeertzjq
2023-02-28 19:04:32 +08:00
parent 3b92776226
commit bfa0bc7df0
5 changed files with 110 additions and 42 deletions

View File

@@ -5859,27 +5859,57 @@ write_blob_error:
return false;
}
/// Read a blob from a file `fd`.
/// Read blob from file "fd".
/// Caller has allocated a blob in "rettv".
///
/// @param[in] fd File to read from.
/// @param[in,out] blob Blob to write to.
/// @param[in,out] rettv Blob to write to.
/// @param[in] offset Read the file from the specified offset.
/// @param[in] size Read the specified size, or -1 if no limit.
///
/// @return true on success, or false on failure.
bool read_blob(FILE *const fd, blob_T *const blob)
/// @return OK on success, or FAIL on failure.
int read_blob(FILE *const fd, typval_T *rettv, off_T offset, off_T size_arg)
FUNC_ATTR_NONNULL_ALL
{
blob_T *const blob = rettv->vval.v_blob;
FileInfo file_info;
if (!os_fileinfo_fd(fileno(fd), &file_info)) {
return false;
return FAIL; // can't read the file, error
}
const int size = (int)os_fileinfo_size(&file_info);
ga_grow(&blob->bv_ga, size);
blob->bv_ga.ga_len = size;
int whence;
off_T size = size_arg;
if (offset >= 0) {
if (size == -1) {
// size may become negative, checked below
size = (off_T)os_fileinfo_size(&file_info) - offset;
}
whence = SEEK_SET;
} else {
if (size == -1) {
size = -offset;
}
whence = SEEK_END;
}
// Trying to read bytes that aren't there results in an empty blob, not an
// error.
if (size < 0 || size > (off_T)os_fileinfo_size(&file_info)) {
return OK;
}
if (vim_fseek(fd, offset, whence) != 0) {
return OK;
}
ga_grow(&blob->bv_ga, (int)size);
blob->bv_ga.ga_len = (int)size;
if (fread(blob->bv_ga.ga_data, 1, (size_t)blob->bv_ga.ga_len, fd)
< (size_t)blob->bv_ga.ga_len) {
return false;
// An empty blob is returned on error.
tv_blob_free(rettv->vval.v_blob);
rettv->vval.v_blob = NULL;
return FAIL;
}
return true;
return OK;
}
/// Saves a typval_T as a string.