diff options
author | Timo Teräs <timo.teras@iki.fi> | 2021-07-17 15:43:08 +0300 |
---|---|---|
committer | Timo Teräs <timo.teras@iki.fi> | 2021-07-22 15:30:08 +0300 |
commit | b559a81694d8a95ac786104516aebf98d04b84bc (patch) | |
tree | 2bd4601015e0d7202c3eb685bf79756022d11b06 | |
parent | 94c5e01038a819e8abd062ed81aec321cdff4aa3 (diff) | |
download | apk-tools-b559a81694d8a95ac786104516aebf98d04b84bc.tar.gz apk-tools-b559a81694d8a95ac786104516aebf98d04b84bc.tar.bz2 apk-tools-b559a81694d8a95ac786104516aebf98d04b84bc.tar.xz apk-tools-b559a81694d8a95ac786104516aebf98d04b84bc.zip |
io: rework apk_istream_get_* to not return erros in blob value
The interface was slightly cumbersome, so replace these functions
to return explicit error, and make the return blob a pointer arg.
-rw-r--r-- | src/adb_walk_text.c | 4 | ||||
-rw-r--r-- | src/apk_blob.h | 1 | ||||
-rw-r--r-- | src/apk_io.h | 6 | ||||
-rw-r--r-- | src/app_convdb.c | 11 | ||||
-rw-r--r-- | src/app_convndx.c | 2 | ||||
-rw-r--r-- | src/app_mkndx.c | 23 | ||||
-rw-r--r-- | src/database.c | 32 | ||||
-rw-r--r-- | src/io.c | 34 | ||||
-rw-r--r-- | src/io_gunzip.c | 17 | ||||
-rw-r--r-- | src/package.c | 4 |
10 files changed, 68 insertions, 66 deletions
diff --git a/src/adb_walk_text.c b/src/adb_walk_text.c index b713f10..972df4f 100644 --- a/src/adb_walk_text.c +++ b/src/adb_walk_text.c @@ -20,12 +20,12 @@ int adb_walk_text(struct adb_walk *d, struct apk_istream *is) uint8_t started[64] = {0}; if (IS_ERR_OR_NULL(is)) return PTR_ERR(is); - l = apk_istream_get_delim(is, token); + if (apk_istream_get_delim(is, token, &l) != 0) goto err; apk_blob_pull_blob_match(&l, APK_BLOB_STR("#%SCHEMA: ")); if ((r = d->ops->schema(d, apk_blob_pull_uint(&l, 16))) != 0) goto err; started[0] = 1; - while (!APK_BLOB_IS_NULL(l = apk_istream_get_delim(is, token))) { + while (apk_istream_get_delim(is, token, &l) == 0) { for (i = 0; l.len >= 2 && l.ptr[0] == ' ' && l.ptr[1] == ' '; i++, l.ptr += 2, l.len -= 2) if (multi_line && i >= multi_line) break; diff --git a/src/apk_blob.h b/src/apk_blob.h index e2c7c4a..2220a75 100644 --- a/src/apk_blob.h +++ b/src/apk_blob.h @@ -64,7 +64,6 @@ static inline const EVP_MD *apk_checksum_default(void) #define APK_BLOB_IS_NULL(blob) ((blob).ptr == NULL) #define APK_BLOB_NULL ((apk_blob_t){0, NULL}) -#define APK_BLOB_ERROR(err) ((apk_blob_t){err, NULL}) #define APK_BLOB_BUF(buf) ((apk_blob_t){sizeof(buf), (char *)(buf)}) #define APK_BLOB_CSUM(csum) ((apk_blob_t){(csum).type, (char *)(csum).data}) #define APK_BLOB_STRUCT(s) ((apk_blob_t){sizeof(s), (char*)&(s)}) diff --git a/src/apk_io.h b/src/apk_io.h index b0971cd..4f03dbc 100644 --- a/src/apk_io.h +++ b/src/apk_io.h @@ -98,9 +98,9 @@ apk_blob_t apk_istream_mmap(struct apk_istream *is); ssize_t apk_istream_read(struct apk_istream *is, void *ptr, size_t size); void *apk_istream_peek(struct apk_istream *is, size_t len); void *apk_istream_get(struct apk_istream *is, size_t len); -apk_blob_t apk_istream_get_max(struct apk_istream *is, size_t size); -apk_blob_t apk_istream_get_delim(struct apk_istream *is, apk_blob_t token); -static inline apk_blob_t apk_istream_get_all(struct apk_istream *is) { return apk_istream_get_max(is, APK_IO_ALL); } +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); } ssize_t apk_istream_splice(struct apk_istream *is, int fd, size_t size, apk_progress_cb cb, void *cb_ctx, struct apk_digest_ctx *dctx); ssize_t apk_stream_copy(struct apk_istream *is, struct apk_ostream *os, size_t size, diff --git a/src/app_convdb.c b/src/app_convdb.c index 7c457a5..f30d0f7 100644 --- a/src/app_convdb.c +++ b/src/app_convdb.c @@ -86,19 +86,17 @@ static int read_triggers(struct conv_ctx *ctx, struct apk_istream *is) if (IS_ERR(is)) return PTR_ERR(is); - while (!APK_BLOB_IS_NULL(l = apk_istream_get_delim(is, nl))) { + while (apk_istream_get_delim(is, nl, &l) == 0) { if (!apk_blob_split(l, spc, &l, &r)) continue; s = find_pkg(ctx, l, ADBI_SCRPT_TRIGGER); if (!s) continue; s->triggers = apk_atomize_dup(&ctx->atoms, r); } - - apk_istream_close(is); - return 0; + return apk_istream_close(is); } -static void convert_idb(struct conv_ctx *ctx, struct apk_istream *is) +static int convert_idb(struct conv_ctx *ctx, struct apk_istream *is) { struct apk_id_cache *idc = apk_ctx_get_id_cache(ctx->ac); struct apk_checksum csum; @@ -117,7 +115,7 @@ static void convert_idb(struct conv_ctx *ctx, struct apk_istream *is) adb_wo_alloca(&pkg, &schema_package, &ctx->dbp); adb_wo_alloca(&acl, &schema_acl, &ctx->dbp); - while (!APK_BLOB_IS_NULL(l = apk_istream_get_delim(is, nl))) { + while (apk_istream_get_delim(is, nl, &l) == 0) { if (l.len < 2) { adb_wa_append_obj(&files, &file); adb_wo_obj(&path, ADBI_DI_FILES, &files); @@ -191,6 +189,7 @@ static void convert_idb(struct conv_ctx *ctx, struct apk_istream *is) break; } } + return apk_istream_close(is); } static int conv_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *args) diff --git a/src/app_convndx.c b/src/app_convndx.c index 6a4e6d7..eb98b5f 100644 --- a/src/app_convndx.c +++ b/src/app_convndx.c @@ -21,7 +21,7 @@ static void convert_index(struct conv_ctx *ctx, struct apk_istream *is) adb_wo_alloca(&pkginfo, &schema_pkginfo, &ctx->dbi); - while (!APK_BLOB_IS_NULL(l = apk_istream_get_delim(is, token))) { + while (apk_istream_get_delim(is, token, &l) == 0) { if (l.len < 2) { adb_wa_append_obj(&ctx->pkgs, &pkginfo); continue; diff --git a/src/app_mkndx.c b/src/app_mkndx.c index bab6983..3316de5 100644 --- a/src/app_mkndx.c +++ b/src/app_mkndx.c @@ -109,33 +109,32 @@ static adb_val_t mkndx_read_v2_pkginfo(struct adb *db, struct apk_istream *is, s }; struct field *f, key; struct adb_obj pkginfo, deps[3]; - apk_blob_t line, l, r, token = APK_BLOB_STR("\n"), bdep; - int e = 0, i = 0; + apk_blob_t line, k, v, token = APK_BLOB_STR("\n"), bdep; + int r, e = 0, i = 0; adb_wo_alloca(&pkginfo, &schema_pkginfo, db); adb_wo_alloca(&deps[0], &schema_dependency_array, db); adb_wo_alloca(&deps[1], &schema_dependency_array, db); adb_wo_alloca(&deps[2], &schema_dependency_array, db); - while (!APK_BLOB_IS_NULL(line = apk_istream_get_delim(is, token))) { + while ((r = apk_istream_get_delim(is, token, &line)) == 0) { if (sctx) apk_sign_ctx_parse_pkginfo_line(sctx, line); if (line.len < 1 || line.ptr[0] == '#') continue; - if (!apk_blob_split(line, APK_BLOB_STR(" = "), &l, &r)) continue; + if (!apk_blob_split(line, APK_BLOB_STR(" = "), &k, &v)) continue; - key.str = l; + key.str = k; f = bsearch(&key, fields, ARRAY_SIZE(fields), sizeof(fields[0]), cmpfield); if (!f || f->ndx == 0) continue; if (adb_ro_val(&pkginfo, f->ndx) != ADB_NULL) { /* Workaround abuild bug that emitted multiple license lines */ if (f->ndx == ADBI_PI_LICENSE) continue; - e = ADB_ERROR(APKE_ADB_PACKAGE_FORMAT); - continue; + return ADB_ERROR(APKE_ADB_PACKAGE_FORMAT); } switch (f->ndx) { case ADBI_PI_ARCH: - if (!APK_BLOB_IS_NULL(rewrite_arch)) r = rewrite_arch; + if (!APK_BLOB_IS_NULL(rewrite_arch)) v = rewrite_arch; break; case ADBI_PI_DEPENDS: i = 0; @@ -146,13 +145,15 @@ static adb_val_t mkndx_read_v2_pkginfo(struct adb *db, struct apk_istream *is, s case ADBI_PI_REPLACES: i = 2; parse_deps: - while (!ADB_IS_ERROR(e) && apk_dep_split(&r, &bdep)) + while (apk_dep_split(&v, &bdep)) { e = adb_wa_append_fromstring(&deps[i], bdep); + if (ADB_IS_ERROR(e)) return e; + } continue; } - adb_wo_pkginfo(&pkginfo, f->ndx, r); + adb_wo_pkginfo(&pkginfo, f->ndx, v); } - if (ADB_IS_ERROR(e)) return e; + if (r != -APKE_EOF) return ADB_ERROR(-r); adb_wo_arr(&pkginfo, ADBI_PI_DEPENDS, &deps[0]); adb_wo_arr(&pkginfo, ADBI_PI_PROVIDES, &deps[1]); diff --git a/src/database.c b/src/database.c index db5015e..35de195 100644 --- a/src/database.c +++ b/src/database.c @@ -727,21 +727,26 @@ int apk_db_read_overlay(struct apk_database *db, struct apk_istream *is) struct apk_package *pkg; struct apk_installed_package *ipkg; apk_blob_t token = APK_BLOB_STR("\n"), line, bdir, bfile; - int r = -1; - if (IS_ERR_OR_NULL(is)) return -1; + if (IS_ERR_OR_NULL(is)) return PTR_ERR(is); pkg = apk_pkg_new(); - if (pkg == NULL) goto err; + if (!pkg) goto no_mem; ipkg = apk_pkg_install(db, pkg); - if (ipkg == NULL) goto err; + if (ipkg == NULL) { + no_mem: + apk_istream_error(is, -ENOMEM); + goto err; + } diri_node = hlist_tail_ptr(&ipkg->owned_dirs); - while (!APK_BLOB_IS_NULL(line = apk_istream_get_delim(is, token))) { - if (!apk_blob_rsplit(line, '/', &bdir, &bfile)) + while (apk_istream_get_delim(is, token, &line) == 0) { + if (!apk_blob_rsplit(line, '/', &bdir, &bfile)) { + apk_istream_error(is, -APKE_V2PKG_FORMAT); break; + } if (bfile.len == 0) { diri = apk_db_diri_new(db, pkg, bdir, &diri_node); @@ -756,10 +761,8 @@ int apk_db_read_overlay(struct apk_database *db, struct apk_istream *is) (void) apk_db_file_get(db, diri, bfile, &file_diri_node); } } - r = 0; err: - apk_istream_close(is); - return r; + return apk_istream_close(is); } int apk_db_index_read(struct apk_database *db, struct apk_istream *is, int repo) @@ -781,7 +784,7 @@ int apk_db_index_read(struct apk_database *db, struct apk_istream *is, int repo) if (IS_ERR_OR_NULL(is)) return PTR_ERR(is); - while (!APK_BLOB_IS_NULL(l = apk_istream_get_delim(is, token))) { + while (apk_istream_get_delim(is, token, &l) == 0) { lineno++; if (l.len < 2) { @@ -901,7 +904,6 @@ int apk_db_index_read(struct apk_database *db, struct apk_istream *is, int repo) } if (APK_BLOB_IS_NULL(l)) goto bad_entry; } - return apk_istream_close(is); old_apk_tools: /* Installed db should not have unsupported fields */ @@ -1135,7 +1137,7 @@ static int apk_db_triggers_read(struct apk_database *db, struct apk_istream *is) if (IS_ERR(is)) return PTR_ERR(is); - while (!APK_BLOB_IS_NULL(l = apk_istream_get_delim(is, APK_BLOB_STR("\n")))) { + while (apk_istream_get_delim(is, APK_BLOB_STR("\n"), &l) == 0) { apk_blob_pull_csum(&l, &csum); apk_blob_pull_char(&l, ' '); @@ -1150,9 +1152,7 @@ static int apk_db_triggers_read(struct apk_database *db, struct apk_istream *is) list_add_tail(&ipkg->trigger_pkgs_list, &db->installed.triggers); } - apk_istream_close(is); - - return 0; + return apk_istream_close(is); } static int apk_db_read_state(struct apk_database *db, int flags) @@ -2428,7 +2428,7 @@ static int apk_db_install_archive_entry(void *_ctx, if (ae->name[0] != '.') return 0; if (strcmp(ae->name, ".PKGINFO") == 0) { apk_blob_t l, token = APK_BLOB_STR("\n"); - while (!APK_BLOB_IS_NULL(l = apk_istream_get_delim(is, token))) + while (apk_istream_get_delim(is, token, &l) == 0) read_info_line(ctx, l); return 0; } @@ -160,21 +160,22 @@ void *apk_istream_get(struct apk_istream *is, size_t len) return p; } -apk_blob_t apk_istream_get_max(struct apk_istream *is, size_t max) +int apk_istream_get_max(struct apk_istream *is, size_t max, apk_blob_t *data) { if (is->ptr == is->end) __apk_istream_fill(is); if (is->ptr != is->end) { - apk_blob_t ret = APK_BLOB_PTR_LEN((char*)is->ptr, min((size_t)(is->end - is->ptr), max)); - is->ptr += ret.len; - return ret; + *data = APK_BLOB_PTR_LEN((char*)is->ptr, min((size_t)(is->end - is->ptr), max)); + is->ptr += data->len; + return 0; } - return (struct apk_blob) { .len = is->err < 0 ? is->err : 0 }; + *data = APK_BLOB_NULL; + return is->err < 0 ? is->err : -APKE_EOF; } -apk_blob_t apk_istream_get_delim(struct apk_istream *is, apk_blob_t token) +int apk_istream_get_delim(struct apk_istream *is, apk_blob_t token, apk_blob_t *data) { apk_blob_t ret = APK_BLOB_NULL, left = APK_BLOB_NULL; @@ -195,9 +196,11 @@ apk_blob_t apk_istream_get_delim(struct apk_istream *is, apk_blob_t token) if (!APK_BLOB_IS_NULL(ret)) { is->ptr = (uint8_t*)left.ptr; is->end = (uint8_t*)left.ptr + left.len; - return ret; + *data = ret; + return 0; } - return (struct apk_blob) { .len = is->err < 0 ? is->err : 0 }; + *data = APK_BLOB_NULL; + return is->err < 0 ? is->err : -APKE_EOF; } static void blob_get_meta(struct apk_istream *is, struct apk_file_meta *meta) @@ -559,11 +562,10 @@ ssize_t apk_stream_copy(struct apk_istream *is, struct apk_ostream *os, size_t s while (done < size) { if (cb != NULL) cb(cb_ctx, done); - d = apk_istream_get_max(is, size - done); - if (APK_BLOB_IS_NULL(d)) { - if (d.len) return d.len; - if (size != APK_IO_ALL) return -APKE_EOF; - break; + r = apk_istream_get_max(is, size - done, &d); + if (r < 0) { + if (r == -APKE_EOF && d.len) return d.len; + return r; } if (dctx) apk_digest_ctx_update(dctx, d.ptr, d.len); @@ -609,7 +611,7 @@ ssize_t apk_istream_splice(struct apk_istream *is, int fd, size_t size, togo = min(size - done, bufsz); r = apk_istream_read(is, buf, togo); if (r <= 0) { - if (r) goto err; + if (r && r != -APKE_EOF) goto err; if (size != APK_IO_ALL && done != size) { r = -APKE_EOF; goto err; @@ -827,12 +829,12 @@ int apk_fileinfo_get(int atfd, const char *filename, unsigned int flags, apk_blob_t blob; if (apk_digest_ctx_init(&dctx, hash_alg) == 0) { - while (!APK_BLOB_IS_NULL(blob = apk_istream_get_all(is))) + while (apk_istream_get_all(is, &blob) == 0) apk_digest_ctx_update(&dctx, blob.ptr, blob.len); apk_digest_ctx_final(&dctx, &fi->digest); apk_digest_ctx_free(&dctx); } - apk_istream_close(is); + return apk_istream_close(is); } } diff --git a/src/io_gunzip.c b/src/io_gunzip.c index e1a23d6..3cab464 100644 --- a/src/io_gunzip.c +++ b/src/io_gunzip.c @@ -67,17 +67,18 @@ static ssize_t gzi_read(struct apk_istream *is, void *ptr, size_t size) APK_BLOB_PTR_LEN(gis->cbprev, (void *)gis->zs.next_in - gis->cbprev)); } - blob = apk_istream_get_all(gis->zis); + r = apk_istream_get_all(gis->zis, &blob); gis->cbprev = blob.ptr; gis->zs.avail_in = blob.len; gis->zs.next_in = (void *) gis->cbprev; - if (blob.len < 0) { - gis->is.err = blob.len; - goto ret; - } else if (gis->zs.avail_in == 0) { - gis->is.err = 1; - gis->cbarg = APK_BLOB_NULL; - gzi_boundary_change(gis); + if (r < 0) { + if (r == -APKE_EOF) { + gis->is.err = 1; + gis->cbarg = APK_BLOB_NULL; + gzi_boundary_change(gis); + } else { + gis->is.err = r; + } goto ret; } } diff --git a/src/package.c b/src/package.c index 89965ab..542edfd 100644 --- a/src/package.c +++ b/src/package.c @@ -643,7 +643,7 @@ int apk_sign_ctx_verify_tar(void *sctx, const struct apk_file_info *fi, if (strcmp(fi->name, ".PKGINFO") == 0) { apk_blob_t l, token = APK_BLOB_STR("\n"); - while (!APK_BLOB_IS_NULL(l = apk_istream_get_delim(is, token))) + while (apk_istream_get_delim(is, token, &l) == 0) apk_sign_ctx_parse_pkginfo_line(ctx, l); } @@ -900,7 +900,7 @@ static int read_info_entry(void *ctx, const struct apk_file_info *ae, if (strcmp(ae->name, ".PKGINFO") == 0) { /* APK 2.0 format */ apk_blob_t l, token = APK_BLOB_STR("\n"); - while (!APK_BLOB_IS_NULL(l = apk_istream_get_delim(is, token))) + while (apk_istream_get_delim(is, token, &l) == 0) read_info_line(ctx, l); } else if (strcmp(ae->name, ".INSTALL") == 0) { apk_warn(&ri->db->ctx->out, |