summaryrefslogtreecommitdiff
path: root/ext/zip/lib/zip_source_filep.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/zip/lib/zip_source_filep.c')
-rw-r--r--ext/zip/lib/zip_source_filep.c34
1 files changed, 19 insertions, 15 deletions
diff --git a/ext/zip/lib/zip_source_filep.c b/ext/zip/lib/zip_source_filep.c
index 4d896a4c01..fcebe73bc6 100644
--- a/ext/zip/lib/zip_source_filep.c
+++ b/ext/zip/lib/zip_source_filep.c
@@ -58,14 +58,14 @@ static zip_int64_t read_file(void *state, void *data, zip_uint64_t len,
-ZIP_EXTERN(struct zip_source *)
+ZIP_EXTERN struct zip_source *
zip_source_filep(struct zip *za, FILE *file, zip_uint64_t start,
zip_int64_t len)
{
if (za == NULL)
return NULL;
- if (file == NULL || start < 0 || len < -1) {
+ if (file == NULL || len < -1) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return NULL;
}
@@ -125,7 +125,8 @@ read_file(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd)
{
struct read_file *z;
char *buf;
- int i, n;
+ zip_uint64_t n;
+ size_t i;
z = (struct read_file *)state;
buf = (char *)data;
@@ -140,7 +141,7 @@ read_file(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd)
}
}
- if (z->closep) {
+ if (z->closep && z->off > 0) {
if (fseeko(z->f, (off_t)z->off, SEEK_SET) < 0) {
z->e[0] = ZIP_ER_SEEK;
z->e[1] = errno;
@@ -151,32 +152,35 @@ read_file(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd)
return 0;
case ZIP_SOURCE_READ:
- /* XXX: return INVAL if len > size_t max */
if (z->remain != -1)
- n = len > z->remain ? z->remain : len;
+ n = len > (zip_uint64_t)z->remain ? (zip_uint64_t)z->remain : len;
else
n = len;
+
+ if (n > SIZE_MAX)
+ n = SIZE_MAX;
if (!z->closep) {
/* we might share this file with others, so let's be safe */
- if (fseeko(z->f, (off_t)(z->off + z->len-z->remain),
- SEEK_SET) < 0) {
+ if (fseeko(z->f, (off_t)(z->off + (zip_uint64_t)(z->len-z->remain)), SEEK_SET) < 0) {
z->e[0] = ZIP_ER_SEEK;
z->e[1] = errno;
return -1;
}
}
- if ((i=fread(buf, 1, n, z->f)) < 0) {
- z->e[0] = ZIP_ER_READ;
- z->e[1] = errno;
- return -1;
+ if ((i=fread(buf, 1, (size_t)n, z->f)) == 0) {
+ if (ferror(z->f)) {
+ z->e[0] = ZIP_ER_READ;
+ z->e[1] = errno;
+ return -1;
+ }
}
if (z->remain != -1)
z->remain -= i;
- return i;
+ return (zip_int64_t)i;
case ZIP_SOURCE_CLOSE:
if (z->fname) {
@@ -214,11 +218,11 @@ read_file(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd)
st->mtime = fst.st_mtime;
st->valid |= ZIP_STAT_MTIME;
if (z->len != -1) {
- st->size = z->len;
+ st->size = (zip_uint64_t)z->len;
st->valid |= ZIP_STAT_SIZE;
}
else if ((fst.st_mode&S_IFMT) == S_IFREG) {
- st->size = fst.st_size;
+ st->size = (zip_uint64_t)fst.st_size;
st->valid |= ZIP_STAT_SIZE;
}
}