From b7ab9fa5432c9bdd95acae7b5d8fd8de1ee6f3f1 Mon Sep 17 00:00:00 2001 From: Timo Teräs Date: Sat, 16 Sep 2023 14:16:48 +0300 Subject: adb: make array length unbounded This adjusts the schema num_fiels on arrays be the initial stack allocation size, but will expand the array to heap on appending array items. apk_wo_free() is introduced and needs to be used when writing array objects. fixes #10855 --- src/adb.c | 21 +++++++++++++++++++-- src/adb.h | 4 +++- src/apk_adb.c | 12 ++++++------ src/apk_adb.h | 7 ------- src/app_convdb.c | 3 +++ src/app_mkndx.c | 12 +++++++----- src/app_mkpkg.c | 8 ++++++-- 7 files changed, 44 insertions(+), 23 deletions(-) diff --git a/src/adb.c b/src/adb.c index e0cc3bc..16b2c8b 100644 --- a/src/adb.c +++ b/src/adb.c @@ -819,6 +819,12 @@ struct adb_obj *adb_wo_init_val(struct adb_obj *o, adb_val_t *p, const struct ad return adb_wo_init(o, p, schema, parent->db); } +void adb_wo_free(struct adb_obj *o) +{ + if (o->dynamic) free(o->obj); + o->obj = 0; +} + void adb_wo_reset(struct adb_obj *o) { uint32_t max = o->obj[ADBI_NUM_ENTRIES]; @@ -930,9 +936,20 @@ adb_val_t adb_wo_arr(struct adb_obj *o, unsigned i, struct adb_obj *no) adb_val_t adb_wa_append(struct adb_obj *o, adb_val_t v) { assert(o->schema->kind == ADB_KIND_ARRAY); - if (o->num >= o->obj[ADBI_NUM_ENTRIES]) return adb_w_error(o->db, E2BIG); if (ADB_IS_ERROR(v)) return adb_w_error(o->db, ADB_VAL_VALUE(v)); - if (v != ADB_VAL_NULL) o->obj[o->num++] = v; + if (v == ADB_VAL_NULL) return v; + + if (o->num >= o->obj[ADBI_NUM_ENTRIES]) { + int num = o->obj[ADBI_NUM_ENTRIES]; + adb_val_t *obj = reallocarray(o->dynamic ? o->obj : NULL, num * 2, sizeof(adb_val_t)); + if (!obj) return adb_w_error(o->db, ENOMEM); + if (!o->dynamic) memcpy(obj, o->obj, sizeof(adb_val_t) * num); + memset(&obj[num], 0, sizeof(adb_val_t) * num); + o->obj = obj; + o->obj[ADBI_NUM_ENTRIES] = num * 2; + o->dynamic = 1; + } + o->obj[o->num++] = v; return v; } diff --git a/src/adb.h b/src/adb.h index 3372c07..7c1869c 100644 --- a/src/adb.h +++ b/src/adb.h @@ -161,8 +161,9 @@ struct adb { struct adb_obj { struct adb *db; const struct adb_object_schema *schema; - uint32_t num; adb_val_t *obj; + uint32_t num; + uint32_t dynamic : 1; }; /* Container read interface */ @@ -214,6 +215,7 @@ adb_val_t adb_w_fromstring(struct adb *, const uint8_t *kind, apk_blob_t); struct adb_obj *adb_wo_init(struct adb_obj *, adb_val_t *, const struct adb_object_schema *, struct adb *); struct adb_obj *adb_wo_init_val(struct adb_obj *, adb_val_t *, const struct adb_obj *, unsigned i); +void adb_wo_free(struct adb_obj *); void adb_wo_reset(struct adb_obj *); void adb_wo_resetdb(struct adb_obj *); adb_val_t adb_w_obj(struct adb_obj *); diff --git a/src/apk_adb.c b/src/apk_adb.c index 0b3f36c..7d8b1fb 100644 --- a/src/apk_adb.c +++ b/src/apk_adb.c @@ -110,7 +110,7 @@ static struct adb_scalar_schema scalar_mstring = { const struct adb_object_schema schema_string_array = { .kind = ADB_KIND_ARRAY, - .num_fields = APK_MAX_PKG_TRIGGERS, + .num_fields = 32, .fields = ADB_ARRAY_ITEM(scalar_string), }; @@ -373,7 +373,7 @@ static int dependencies_fromstring(struct adb_obj *obj, apk_blob_t b) const struct adb_object_schema schema_dependency_array = { .kind = ADB_KIND_ARRAY, .fromstring = dependencies_fromstring, - .num_fields = APK_MAX_PKG_DEPENDENCIES, + .num_fields = 32, .pre_commit = adb_wa_sort_unique, .fields = ADB_ARRAY_ITEM(schema_dependency), }; @@ -408,7 +408,7 @@ const struct adb_object_schema schema_pkginfo = { const struct adb_object_schema schema_pkginfo_array = { .kind = ADB_KIND_ARRAY, - .num_fields = APK_MAX_INDEX_PACKAGES, + .num_fields = 128, .pre_commit = adb_wa_sort, .fields = ADB_ARRAY_ITEM(schema_pkginfo), }; @@ -450,7 +450,7 @@ const struct adb_object_schema schema_file = { const struct adb_object_schema schema_file_array = { .kind = ADB_KIND_ARRAY, .pre_commit = adb_wa_sort, - .num_fields = APK_MAX_MANIFEST_FILES, + .num_fields = 128, .fields = ADB_ARRAY_ITEM(schema_file), }; @@ -468,7 +468,7 @@ const struct adb_object_schema schema_dir = { const struct adb_object_schema schema_dir_array = { .kind = ADB_KIND_ARRAY, .pre_commit = adb_wa_sort, - .num_fields = APK_MAX_MANIFEST_PATHS, + .num_fields = 128, .fields = ADB_ARRAY_ITEM(schema_dir), }; @@ -508,7 +508,7 @@ const struct adb_adb_schema schema_package_adb = { const struct adb_object_schema schema_package_adb_array = { .kind = ADB_KIND_ARRAY, .pre_commit = adb_wa_sort, - .num_fields = APK_MAX_INDEX_PACKAGES, + .num_fields = 128, .fields = ADB_ARRAY_ITEM(schema_package_adb), }; diff --git a/src/apk_adb.h b/src/apk_adb.h index 45c06f1..0bc46e9 100644 --- a/src/apk_adb.h +++ b/src/apk_adb.h @@ -89,13 +89,6 @@ struct adb_data_package { #define ADBI_IDB_MAX 0x02 /* */ -#define APK_MAX_PKG_DEPENDENCIES 512 -#define APK_MAX_PKG_REPLACES 32 -#define APK_MAX_PKG_TRIGGERS 32 -#define APK_MAX_INDEX_PACKAGES 20000 -#define APK_MAX_MANIFEST_FILES 12000 -#define APK_MAX_MANIFEST_PATHS 6000 - extern const struct adb_object_schema schema_dependency, schema_dependency_array, schema_pkginfo, schema_pkginfo_array, diff --git a/src/app_convdb.c b/src/app_convdb.c index 5e60115..f27c03d 100644 --- a/src/app_convdb.c +++ b/src/app_convdb.c @@ -190,6 +190,9 @@ static int convert_idb(struct conv_ctx *ctx, struct apk_istream *is) break; } } + adb_wo_free(&triggers); + adb_wo_free(&files); + adb_wo_free(&paths); return apk_istream_close(is); } diff --git a/src/app_mkndx.c b/src/app_mkndx.c index 3313804..d7f1d26 100644 --- a/src/app_mkndx.c +++ b/src/app_mkndx.c @@ -219,7 +219,7 @@ static int mkndx_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *a ADB_SCHEMA_INDEX, trust); if (r) { apk_err(out, "%s: %s", ctx->index, apk_error_str(r)); - return r; + goto done; } adb_ro_obj(adb_r_rootobj(&odb, &oroot, &schema_index), ADBI_NDX_PACKAGES, &opkgs); } @@ -286,7 +286,8 @@ static int mkndx_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *a } if (errors) { apk_err(out, "%d errors, not creating index", errors); - return -1; + r = -1; + goto done; } numpkgs = adb_ra_num(&ctx->pkgs); @@ -298,14 +299,15 @@ static int mkndx_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *a apk_ostream_to_file(AT_FDCWD, ctx->output, 0644), &ctx->db, trust); - adb_free(&ctx->db); - adb_free(&odb); - if (r == 0) apk_msg(out, "Index has %d packages (of which %d are new)", numpkgs, newpkgs); else apk_err(out, "Index creation failed: %s", apk_error_str(r)); +done: + adb_wo_free(&ctx->pkgs); + adb_free(&ctx->db); + adb_free(&odb); #if 0 apk_hash_foreach(&db->available.names, warn_if_no_providers, &counts); diff --git a/src/app_mkpkg.c b/src/app_mkpkg.c index 74c8db8..552ef57 100644 --- a/src/app_mkpkg.c +++ b/src/app_mkpkg.c @@ -155,12 +155,14 @@ static int mkpkg_process_directory(struct mkpkg_ctx *ctx, int dirfd, struct apk_ if (r) { apk_err(out, "failed to process directory '%s': %d", apk_pathbuilder_cstr(&ctx->pb), r); - return r; + goto done; } adb_wo_obj(&fio, ADBI_DI_FILES, &files); adb_wa_append_obj(&ctx->paths, &fio); - return 0; +done: + adb_wo_free(&files); + return r; } static int mkpkg_process_dirent(void *pctx, int dirfd, const char *entry) @@ -343,6 +345,7 @@ static int mkpkg_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *a for (i = 0; i < ctx->triggers->num; i++) adb_wa_append_fromstring(&triggers, APK_BLOB_STR(ctx->triggers->item[i])); adb_wo_obj(&pkg, ADBI_PKG_TRIGGERS, &triggers); + adb_wo_free(&triggers); } adb_w_rootobj(&pkg); @@ -401,6 +404,7 @@ static int mkpkg_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *a r = apk_ostream_close(os); err: + adb_wo_free(&ctx->paths); adb_free(&ctx->db); if (r) apk_err(out, "failed to create package: %s: %s", ctx->output, apk_error_str(r)); return r; -- cgit v1.2.3-60-g2f50