summaryrefslogtreecommitdiff
path: root/src/blob.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/blob.c')
-rw-r--r--src/blob.c26
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;