summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2023-09-16 14:16:48 +0300
committerTimo Teräs <timo.teras@iki.fi>2023-09-16 14:16:48 +0300
commitb7ab9fa5432c9bdd95acae7b5d8fd8de1ee6f3f1 (patch)
tree8a4eeca04c30980d8830644a23b30e75e44dc92c
parent23de40cd360841db94c08a509eb12cc6a8eb1b28 (diff)
downloadapk-tools-b7ab9fa5432c9bdd95acae7b5d8fd8de1ee6f3f1.tar.gz
apk-tools-b7ab9fa5432c9bdd95acae7b5d8fd8de1ee6f3f1.tar.bz2
apk-tools-b7ab9fa5432c9bdd95acae7b5d8fd8de1ee6f3f1.tar.xz
apk-tools-b7ab9fa5432c9bdd95acae7b5d8fd8de1ee6f3f1.zip
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
-rw-r--r--src/adb.c21
-rw-r--r--src/adb.h4
-rw-r--r--src/apk_adb.c12
-rw-r--r--src/apk_adb.h7
-rw-r--r--src/app_convdb.c3
-rw-r--r--src/app_mkndx.c12
-rw-r--r--src/app_mkpkg.c8
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;