diff options
Diffstat (limited to 'src/blob.c')
-rw-r--r-- | src/blob.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/src/blob.c b/src/blob.c index a94316c13..311b87e49 100644 --- a/src/blob.c +++ b/src/blob.c @@ -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; |