From 0f5147a67baf535849d8d261f2da8e91d7473179 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 31 Jul 2024 17:36:45 +0200 Subject: [PATCH] pw-cli: support arbitrary large params and commands Use a memstream to collect the arguments so that it can dynamically allocate as much memory as necessary. Use a dynamic pod builder to construct the pods so that they can be of arbitrary size. Fixes #4166 --- src/tools/pw-cli.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/tools/pw-cli.c b/src/tools/pw-cli.c index 2b1d6c8ac..c7b6a9eb8 100644 --- a/src/tools/pw-cli.c +++ b/src/tools/pw-cli.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include @@ -1748,10 +1748,12 @@ static bool do_set_param(struct data *data, const char *cmd, char *args, char ** uint32_t param_id; struct global *global; uint8_t buffer[1024]; - struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); + spa_auto(spa_pod_dynamic_builder) b = { 0 }; const struct spa_type_info *ti; struct spa_pod *pod; + spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096); + n = pw_split_ip(args, WHITESPACE, 3, a); if (n < 3) { *error = spa_aprintf("%s ", cmd); @@ -1773,11 +1775,11 @@ static bool do_set_param(struct data *data, const char *cmd, char *args, char ** *error = spa_aprintf("%s: unknown param type: %s", cmd, a[1]); return false; } - if ((res = spa_json_to_pod(&b, 0, ti, a[2], strlen(a[2]))) < 0) { + if ((res = spa_json_to_pod(&b.b, 0, ti, a[2], strlen(a[2]))) < 0) { *error = spa_aprintf("%s: can't make pod: %s", cmd, spa_strerror(res)); return false; } - if ((pod = spa_pod_builder_deref(&b, 0)) == NULL) { + if ((pod = spa_pod_builder_deref(&b.b, 0)) == NULL) { *error = spa_aprintf("%s: can't make pod", cmd); return false; } @@ -1882,10 +1884,12 @@ static bool do_send_command(struct data *data, const char *cmd, char *args, char int res, n; struct global *global; uint8_t buffer[1024]; - struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); + spa_auto(spa_pod_dynamic_builder) b = { 0 }; const struct spa_type_info *ti; struct spa_pod *pod; + spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096); + n = pw_split_ip(args, WHITESPACE, 3, a); if (n < 3) { *error = spa_aprintf("%s ", cmd); @@ -1914,11 +1918,11 @@ static bool do_send_command(struct data *data, const char *cmd, char *args, char *error = spa_aprintf("%s: unknown node command type: %s", cmd, a[1]); return false; } - if ((res = spa_json_to_pod(&b, 0, ti, a[2], strlen(a[2]))) < 0) { + if ((res = spa_json_to_pod(&b.b, 0, ti, a[2], strlen(a[2]))) < 0) { *error = spa_aprintf("%s: can't make pod: %s", cmd, spa_strerror(res)); return false; } - if ((pod = spa_pod_builder_deref(&b, 0)) == NULL) { + if ((pod = spa_pod_builder_deref(&b.b, 0)) == NULL) { *error = spa_aprintf("%s: can't make pod", cmd); return false; } @@ -2358,20 +2362,23 @@ int main(int argc, char *argv[]) readline_cleanup(); #endif } else { - char buf[4096], *p, *error; + FILE *buf; + char *error, *ptr; + size_t size; - p = buf; - for (i = optind; i < argc; i++) { - p = stpcpy(p, argv[i]); - p = stpcpy(p, " "); - } + buf = open_memstream(&ptr, &size); + for (i = optind; i < argc; i++) + fprintf(buf, "%s%s", i == optind ? "" : " ", argv[i]); + fclose(buf); pw_main_loop_run(data.loop); - if (!parse(&data, buf, &error)) { + if (!parse(&data, ptr, &error)) { fprintf(stderr, "Error: \"%s\"\n", error); free(error); } + free(ptr); + if (data.current != NULL) data.current->prompt_pending = pw_core_sync(data.current->core, 0, 0);