mirror of
https://github.com/rizinorg/rizin
synced 2026-08-22 20:26:16 -04:00
Add exclusions to config saving (#6629)
This will be used for future experimental options that are subject to frequent change and should not pollute projects.
This commit is contained in:
parent
cd1ad98598
commit
9b57c7a8ec
6 changed files with 115 additions and 51 deletions
|
|
@ -5,15 +5,40 @@
|
|||
#include <rz_util/rz_serialize.h>
|
||||
#include "config_internal.h"
|
||||
|
||||
static RzSetS *build_exclude_set(const char **strings) {
|
||||
if (!strings) {
|
||||
return NULL;
|
||||
}
|
||||
HtSP *r = rz_set_s_new(HT_STR_DUP);
|
||||
if (!r) {
|
||||
return NULL;
|
||||
}
|
||||
for (; *strings; strings++) {
|
||||
rz_set_s_add(r, *strings);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
typedef struct serialze_ctx_t {
|
||||
Sdb *db;
|
||||
HtSP *exclude;
|
||||
} SerializeCtx;
|
||||
|
||||
static bool config_serialize_to_sdb(const RzConfigEntry *entry, void *user) {
|
||||
Sdb *db = user;
|
||||
SerializeCtx *ctx = user;
|
||||
if (entry->is_variable) {
|
||||
if (ctx->exclude && rz_set_s_contains(ctx->exclude, entry->var.name)) {
|
||||
return true;
|
||||
}
|
||||
char *value = rz_config_var_as_string(&entry->var);
|
||||
sdb_set(db, entry->var.name, value);
|
||||
sdb_set(ctx->db, entry->var.name, value);
|
||||
free(value);
|
||||
} else {
|
||||
const RzConfigNode *node = &entry->node;
|
||||
sdb_set(db, node->name, node->value);
|
||||
if (ctx->exclude && rz_set_s_contains(ctx->exclude, node->name)) {
|
||||
return true;
|
||||
}
|
||||
sdb_set(ctx->db, node->name, node->value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -28,20 +53,27 @@ static bool config_serialize_to_sdb(const RzConfigEntry *entry, void *user) {
|
|||
* <name>=<value>
|
||||
* ...
|
||||
*
|
||||
* \param exclude NULL-terminated array of keys to not store in the sdb.
|
||||
*/
|
||||
RZ_API void rz_serialize_config_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzConfig *config) {
|
||||
rz_config_iterate_over(config, config_serialize_to_sdb, db);
|
||||
RZ_API void rz_serialize_config_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzConfig *config, RZ_NULLABLE const char **exclude) {
|
||||
rz_return_if_fail(db && config);
|
||||
SerializeCtx ctx = { .db = db, .exclude = build_exclude_set(exclude) };
|
||||
if (exclude && !ctx.exclude) {
|
||||
return;
|
||||
}
|
||||
rz_config_iterate_over(config, config_serialize_to_sdb, &ctx);
|
||||
rz_set_s_free(ctx.exclude);
|
||||
}
|
||||
|
||||
typedef struct deserialize_ctx_s {
|
||||
typedef struct deserialize_ctx_t {
|
||||
RzConfig *config;
|
||||
HtSP *exclude;
|
||||
RzSetS *exclude;
|
||||
} DeserializeCtx;
|
||||
|
||||
static bool config_deserialize_from_sdb(void *user, const SdbKv *kv) {
|
||||
DeserializeCtx *ctx = user;
|
||||
const char *key = sdbkv_key(kv);
|
||||
if (ctx->exclude && ht_sp_find_kv(ctx->exclude, key, NULL)) {
|
||||
if (ctx->exclude && rz_set_s_contains(ctx->exclude, key)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -65,17 +97,11 @@ static bool config_deserialize_from_sdb(void *user, const SdbKv *kv) {
|
|||
RZ_API bool rz_serialize_config_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzConfig *config, RZ_NULLABLE const char **exclude) {
|
||||
rz_return_val_if_fail(db && config, false);
|
||||
|
||||
DeserializeCtx ctx = { config, NULL };
|
||||
if (exclude) {
|
||||
ctx.exclude = ht_sp_new(HT_STR_DUP, NULL, NULL);
|
||||
if (!ctx.exclude) {
|
||||
return false;
|
||||
}
|
||||
for (; *exclude; exclude++) {
|
||||
ht_sp_insert(ctx.exclude, *exclude, NULL);
|
||||
}
|
||||
DeserializeCtx ctx = { .config = config, .exclude = build_exclude_set(exclude) };
|
||||
if (exclude && !ctx.exclude) {
|
||||
return false;
|
||||
}
|
||||
sdb_foreach(db, config_deserialize_from_sdb, &ctx);
|
||||
ht_sp_free(ctx.exclude);
|
||||
rz_set_s_free(ctx.exclude);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -609,7 +609,7 @@ RZ_API void rz_core_sysenv_begin(RzCore *core) {
|
|||
rz_sys_setenv("RZ_ENDIAN", rz_asm_is_big_endian_set(core->rasm) ? "big" : "little");
|
||||
rz_sys_setenv("RZ_BSIZE", rz_strf(tmpbuf, "%d", core->blocksize));
|
||||
|
||||
// dump current config file so other r2 tools can use the same options
|
||||
// dump current config file so other rizin tools can use the same options
|
||||
char *config_sdb_path = NULL;
|
||||
int config_sdb_fd = rz_file_mkstemp(NULL, &config_sdb_path);
|
||||
if (config_sdb_fd >= 0) {
|
||||
|
|
@ -617,7 +617,7 @@ RZ_API void rz_core_sysenv_begin(RzCore *core) {
|
|||
}
|
||||
|
||||
Sdb *config_sdb = sdb_new(NULL, config_sdb_path, 0);
|
||||
rz_serialize_config_save(config_sdb, core->config);
|
||||
rz_serialize_config_save(config_sdb, core->config, NULL);
|
||||
sdb_sync(config_sdb);
|
||||
sdb_free(config_sdb);
|
||||
rz_sys_setenv("RZ_CONFIG", config_sdb_path);
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ static char *config_path(RzCore *core) {
|
|||
free(path);
|
||||
return NULL;
|
||||
}
|
||||
rz_serialize_config_save(sdb, core->config);
|
||||
rz_serialize_config_save(sdb, core->config, NULL);
|
||||
sdb_sync(sdb);
|
||||
sdb_free(sdb);
|
||||
|
||||
|
|
|
|||
|
|
@ -22,28 +22,20 @@ static void file_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzCore *core, RZ_NULLABLE c
|
|||
static bool file_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzCore *core, RZ_NULLABLE const char *prj_file,
|
||||
RZ_NULLABLE RzSerializeResultInfo *res);
|
||||
|
||||
RZ_API void rz_serialize_core_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzCore *core, RZ_NULLABLE const char *prj_file) {
|
||||
file_save(sdb_ns(db, "file", true), core, prj_file);
|
||||
rz_serialize_config_save(sdb_ns(db, "config", true), core->config);
|
||||
rz_serialize_flag_save(sdb_ns(db, "flags", true), core->flags);
|
||||
rz_serialize_mark_save(sdb_ns(db, "marks", true), core->marks);
|
||||
rz_serialize_analysis_save(sdb_ns(db, "analysis", true), core->analysis);
|
||||
rz_serialize_debug_save(sdb_ns(db, "debug", true), core->dbg);
|
||||
rz_serialize_core_seek_save(sdb_ns(db, "seek", true), core);
|
||||
/*
|
||||
* Config Exclusions:
|
||||
* Most exlusions only affect loading and are still written to the file, in case
|
||||
* they become interesting to load later, or for informative purposes.
|
||||
* Some other config vars may be considered experimental and subject to frequent change,
|
||||
* so they should also be exluded from saving to avoid polluting project files and
|
||||
* having to introduce migrations.
|
||||
*/
|
||||
|
||||
char buf[0x20];
|
||||
if (snprintf(buf, sizeof(buf), "0x%" PFMT64x, core->offset) < 0) {
|
||||
return;
|
||||
}
|
||||
sdb_set(db, "offset", buf);
|
||||
static const char *config_exclude_save[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
if (snprintf(buf, sizeof(buf), "0x%" PFMT32x, core->blocksize) < 0) {
|
||||
return;
|
||||
}
|
||||
sdb_set(db, "blocksize", buf);
|
||||
}
|
||||
|
||||
static const char *config_exclude[] = {
|
||||
static const char *config_exclude_load[] = {
|
||||
"dir.home",
|
||||
"dir.libs",
|
||||
"dir.magic",
|
||||
|
|
@ -70,6 +62,27 @@ static const char *config_exclude[] = {
|
|||
NULL
|
||||
};
|
||||
|
||||
RZ_API void rz_serialize_core_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzCore *core, RZ_NULLABLE const char *prj_file) {
|
||||
file_save(sdb_ns(db, "file", true), core, prj_file);
|
||||
rz_serialize_config_save(sdb_ns(db, "config", true), core->config, config_exclude_save);
|
||||
rz_serialize_flag_save(sdb_ns(db, "flags", true), core->flags);
|
||||
rz_serialize_mark_save(sdb_ns(db, "marks", true), core->marks);
|
||||
rz_serialize_analysis_save(sdb_ns(db, "analysis", true), core->analysis);
|
||||
rz_serialize_debug_save(sdb_ns(db, "debug", true), core->dbg);
|
||||
rz_serialize_core_seek_save(sdb_ns(db, "seek", true), core);
|
||||
|
||||
char buf[0x20];
|
||||
if (snprintf(buf, sizeof(buf), "0x%" PFMT64x, core->offset) < 0) {
|
||||
return;
|
||||
}
|
||||
sdb_set(db, "offset", buf);
|
||||
|
||||
if (snprintf(buf, sizeof(buf), "0x%" PFMT32x, core->blocksize) < 0) {
|
||||
return;
|
||||
}
|
||||
sdb_set(db, "blocksize", buf);
|
||||
}
|
||||
|
||||
RZ_API bool rz_serialize_core_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzCore *core, bool load_bin_io,
|
||||
RZ_NULLABLE const char *prj_file, RZ_NULLABLE RzSerializeResultInfo *res) {
|
||||
Sdb *subdb;
|
||||
|
|
@ -79,7 +92,7 @@ RZ_API bool rz_serialize_core_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzCore *core,
|
|||
if (load_bin_io) {
|
||||
SUB("file", file_load(subdb, core, prj_file, res));
|
||||
}
|
||||
SUB("config", rz_serialize_config_load(subdb, core->config, config_exclude));
|
||||
SUB("config", rz_serialize_config_load(subdb, core->config, config_exclude_load));
|
||||
SUB("flags", rz_serialize_flag_load(subdb, core->flags, res));
|
||||
SUB("marks", rz_serialize_mark_load(subdb, core->marks, res));
|
||||
SUB("analysis", rz_serialize_analysis_load(subdb, core->analysis, res));
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@ static inline bool rz_config_node_is_str(const RzConfigNode *node) {
|
|||
|
||||
/* serialize */
|
||||
|
||||
RZ_API void rz_serialize_config_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzConfig *config);
|
||||
RZ_API void rz_serialize_config_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzConfig *config, RZ_NULLABLE const char **exclude);
|
||||
RZ_API bool rz_serialize_config_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzConfig *config, RZ_NULLABLE const char **exclude);
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -5,10 +5,12 @@
|
|||
#include "minunit.h"
|
||||
#include "test_sdb.h"
|
||||
|
||||
Sdb *ref_db() {
|
||||
Sdb *ref_db(bool excluded) {
|
||||
Sdb *db = sdb_new0();
|
||||
sdb_set(db, "somestring", "somevalue");
|
||||
sdb_set(db, "someint", "42");
|
||||
if (!excluded) {
|
||||
sdb_set(db, "somestring", "somevalue");
|
||||
sdb_set(db, "someint", "42");
|
||||
}
|
||||
sdb_set(db, "somebiggerint", "0x00001337");
|
||||
return db;
|
||||
}
|
||||
|
|
@ -20,10 +22,32 @@ bool test_config_save() {
|
|||
rz_config_set_i(config, "somebiggerint", 0x1337);
|
||||
|
||||
Sdb *db = sdb_new0();
|
||||
rz_serialize_config_save(db, config);
|
||||
rz_serialize_config_save(db, config, NULL);
|
||||
rz_config_free(config);
|
||||
|
||||
Sdb *expected = ref_db();
|
||||
Sdb *expected = ref_db(false);
|
||||
assert_sdb_eq(db, expected, "config save");
|
||||
sdb_free(db);
|
||||
sdb_free(expected);
|
||||
mu_end;
|
||||
}
|
||||
|
||||
bool test_config_save_exclude() {
|
||||
static const char *exclude[] = {
|
||||
"somestring",
|
||||
"someint",
|
||||
NULL
|
||||
};
|
||||
RzConfig *config = rz_config_new(NULL);
|
||||
rz_config_set(config, "somestring", "somevalue");
|
||||
rz_config_set_i(config, "someint", 42);
|
||||
rz_config_set_i(config, "somebiggerint", 0x1337);
|
||||
|
||||
Sdb *db = sdb_new0();
|
||||
rz_serialize_config_save(db, config, exclude);
|
||||
rz_config_free(config);
|
||||
|
||||
Sdb *expected = ref_db(true);
|
||||
assert_sdb_eq(db, expected, "config save");
|
||||
sdb_free(db);
|
||||
sdb_free(expected);
|
||||
|
|
@ -36,7 +60,7 @@ bool test_config_load() {
|
|||
rz_config_set_i(config, "someint", 0);
|
||||
rz_config_set_i(config, "somebiggerint", 0);
|
||||
|
||||
Sdb *db = ref_db();
|
||||
Sdb *db = ref_db(false);
|
||||
sdb_set(db, "sneaky", "not part of config");
|
||||
bool loaded = rz_serialize_config_load(db, config, NULL);
|
||||
sdb_free(db);
|
||||
|
|
@ -61,7 +85,7 @@ bool test_config_load_exclude() {
|
|||
rz_config_set_i(config, "someint", 123);
|
||||
rz_config_set_i(config, "somebiggerint", 0);
|
||||
|
||||
Sdb *db = ref_db();
|
||||
Sdb *db = ref_db(false); // must load non-excluded here!
|
||||
bool loaded = rz_serialize_config_load(db, config, exclude);
|
||||
sdb_free(db);
|
||||
mu_assert("load success", loaded);
|
||||
|
|
@ -76,9 +100,10 @@ bool test_config_load_exclude() {
|
|||
|
||||
int all_tests() {
|
||||
mu_run_test(test_config_save);
|
||||
mu_run_test(test_config_save_exclude);
|
||||
mu_run_test(test_config_load);
|
||||
mu_run_test(test_config_load_exclude);
|
||||
return tests_passed != tests_run;
|
||||
}
|
||||
|
||||
mu_main(all_tests)
|
||||
mu_main(all_tests)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue