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.
cute-signatures
Timo Teräs 2021-07-17 15:43:08 +03:00
parent 94c5e01038
commit b559a81694
10 changed files with 68 additions and 66 deletions

View File

@ -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;

View File

@ -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)})

View File

@ -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,

View File

@ -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)

View File

@ -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;

View File

@ -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]);

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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,