diff --git a/src/adb.c b/src/adb.c index 398c9b2877826dc89c2d1fd8870a28b0bdf273ab..fee76b9960b5b4de19f618e295cf32854f1cf1ac 100644 --- a/src/adb.c +++ b/src/adb.c @@ -313,7 +313,7 @@ static int __adb_m_stream(struct adb *db, struct apk_istream *is, uint32_t expec if (r < 0) break; skip_padding: - r = apk_istream_read(is, 0, adb_block_padding(&blk)); + r = apk_istream_skip(is, adb_block_padding(&blk)); if (r < 0) break; } while (1); err: diff --git a/src/apk_io.h b/src/apk_io.h index 6ec643ba433deeea01050fc509f6c63f823823c2..3cf48697fd33b35323d7c9fac1c6910e73fab928 100644 --- a/src/apk_io.h +++ b/src/apk_io.h @@ -110,6 +110,7 @@ void *apk_istream_get(struct apk_istream *is, size_t len); int apk_istream_get_max(struct apk_istream *is, size_t size, apk_blob_t *data); int apk_istream_get_delim(struct apk_istream *is, apk_blob_t token, apk_blob_t *data); static inline int apk_istream_get_all(struct apk_istream *is, apk_blob_t *data) { return apk_istream_get_max(is, APK_IO_ALL, data); } +int apk_istream_skip(struct apk_istream *is, uint64_t size); int64_t apk_stream_copy(struct apk_istream *is, struct apk_ostream *os, uint64_t size, struct apk_digest_ctx *dctx); static inline struct apk_istream *apk_istream_from_url(const char *url, time_t since) diff --git a/src/extract_v3.c b/src/extract_v3.c index 62cb69a75d8ce27dbfa5616aa16e322bd9d2ddff..a8083e4d8d4a855c4107eb87a77998edcdc4b679 100644 --- a/src/extract_v3.c +++ b/src/extract_v3.c @@ -231,7 +231,7 @@ static int apk_extract_v3_verify_meta(struct apk_extract_ctx *ectx, struct adb_o static int apk_extract_v3_verify_file(struct apk_extract_ctx *ectx, const struct apk_file_info *fi, struct apk_istream *is) { if (is) { - apk_istream_read(is, 0, fi->size); + apk_istream_skip(is, fi->size); return apk_istream_close(is); } return 0; diff --git a/src/io.c b/src/io.c index 065e985f68655f323a71d1e0aaae64f18422dea2..28b07f81af6e246e2c8e535b01aaa1419fef6d48 100644 --- a/src/io.c +++ b/src/io.c @@ -97,17 +97,15 @@ ssize_t apk_istream_read_max(struct apk_istream *is, void *ptr, size_t size) while (left) { if (is->ptr != is->end) { r = min(left, is->end - is->ptr); - if (ptr) { - memcpy(ptr, is->ptr, r); - ptr += r; - } + memcpy(ptr, is->ptr, r); + ptr += r; is->ptr += r; left -= r; continue; } if (is->err) break; - if (ptr && left > is->buf_size/4) { + if (left > is->buf_size/4) { r = is->ops->read(is, ptr, left); if (r <= 0) break; left -= r; @@ -283,14 +281,10 @@ static ssize_t segment_read(struct apk_istream *is, void *ptr, size_t size) static int segment_close(struct apk_istream *is) { - int r = is->err; struct apk_segment_istream *sis = container_of(is, struct apk_segment_istream, is); - if (sis->bytes_left) { - apk_istream_read(sis->pis, NULL, sis->bytes_left); - sis->bytes_left = 0; - } - return r < 0 ? r : 0; + if (sis->bytes_left) apk_istream_skip(is, sis->bytes_left); + return is->err < 0 ? is->err : 0; } static const struct apk_istream_ops segment_istream_ops = { @@ -628,6 +622,22 @@ struct apk_istream *__apk_istream_from_file(int atfd, const char *file, int try_ return apk_istream_from_fd(fd); } +int apk_istream_skip(struct apk_istream *is, uint64_t size) +{ + uint64_t done = 0; + apk_blob_t d; + int r; + + if (IS_ERR(is)) return PTR_ERR(is); + + while (done < size) { + r = apk_istream_get_max(is, min(size - done, SSIZE_MAX), &d); + if (r < 0) return r; + done += d.len; + } + return done; +} + int64_t apk_stream_copy(struct apk_istream *is, struct apk_ostream *os, uint64_t size, struct apk_digest_ctx *dctx) { uint64_t done = 0; diff --git a/src/tar.c b/src/tar.c index 752d983e8c6a139f40a3fbfc2635348e1fab96ec..14e6a56c9d2bbee0c40f22a61af015fb594cf8c2 100644 --- a/src/tar.c +++ b/src/tar.c @@ -239,7 +239,7 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser, paxlen = 0; } - if (toskip && (r = apk_istream_read(is, NULL, toskip)) < 0) + if (toskip && (r = apk_istream_skip(is, toskip)) < 0) goto err; }