[PATCH v2 1/1] cmd/setexpr: support concatenation of direct strings

The setexpr.s command allows to concatenate two strings.
According to the description in doc/usage/cmd/setexpr.rst the parameters value1 and value2 can be either direct values or pointers to a memory location holding the values.
Unfortunately `setexpr.s <value1> + <value2>` fails if any of the values is a direct value. $? is set to false.
* Add support for direct values in setexpr.s. * Correct the unit test for "setexpr.s fred 0". * Add a new unit test for "setexpr.s fred '1' + '3'" giving '13'.
Signed-off-by: Heinrich Schuchardt heinrich.schuchardt@canonical.com --- v2: Update the commit message to indicate that a bug is corrected. --- cmd/setexpr.c | 54 ++++++++++++++++++++++++++++++++-------------- test/cmd/setexpr.c | 7 +++++- 2 files changed, 44 insertions(+), 17 deletions(-)
diff --git a/cmd/setexpr.c b/cmd/setexpr.c index e111b8ba98a..c45fa85c887 100644 --- a/cmd/setexpr.c +++ b/cmd/setexpr.c @@ -35,9 +35,37 @@ struct expr_arg { }; };
+/** + * arg_set_str() - copy string to expression argument + * + * The string is truncated to 64 KiB plus NUL terminator. + * + * @p: pointer to string + * @argp: pointer to expression argument + * Return: 0 on success, -ENOMEM if out of memory + */ +static int arg_set_str(void *p, struct expr_arg *argp) +{ + int len; + char *str; + + /* Maximum string length of 64 KiB plus NUL terminator */ + len = strnlen((char *)p, SZ_64K) + 1; + str = malloc(len); + if (!str) { + printf("Out of memory\n"); + return -ENOMEM; + } + memcpy(str, p, len); + str[len - 1] = '\0'; + argp->sval = str; + return 0; +} + static int get_arg(char *s, int w, struct expr_arg *argp) { struct expr_arg arg; + int ret;
/* * If the parameter starts with a '*' then assume it is a pointer to @@ -47,8 +75,6 @@ static int get_arg(char *s, int w, struct expr_arg *argp) ulong *p; ulong addr; ulong val; - int len; - char *str;
addr = hextoul(&s[1], NULL); switch (w) { @@ -66,18 +92,10 @@ static int get_arg(char *s, int w, struct expr_arg *argp) break; case CMD_DATA_SIZE_STR: p = map_sysmem(addr, SZ_64K); - - /* Maximum string length of 64KB plus terminator */ - len = strnlen((char *)p, SZ_64K) + 1; - str = malloc(len); - if (!str) { - printf("Out of memory\n"); - return -ENOMEM; - } - memcpy(str, p, len); - str[len - 1] = '\0'; + ret = arg_set_str(p, &arg); unmap_sysmem(p); - arg.sval = str; + if (ret) + return ret; break; case 4: p = map_sysmem(addr, sizeof(u32)); @@ -93,9 +111,13 @@ static int get_arg(char *s, int w, struct expr_arg *argp) break; } } else { - if (w == CMD_DATA_SIZE_STR) - return -EINVAL; - arg.ival = hextoul(s, NULL); + if (w == CMD_DATA_SIZE_STR) { + ret = arg_set_str(s, &arg); + if (ret) + return ret; + } else { + arg.ival = hextoul(s, NULL); + } } *argp = arg;
diff --git a/test/cmd/setexpr.c b/test/cmd/setexpr.c index 21a3268bd81..00d373f35ae 100644 --- a/test/cmd/setexpr.c +++ b/test/cmd/setexpr.c @@ -310,7 +310,8 @@ static int setexpr_test_str(struct unit_test_state *uts) ut_assertok(env_set("fred", "x")); start_mem = ut_check_free(); strcpy(buf, "hello"); - ut_asserteq(1, run_command("setexpr.s fred 0", 0)); + ut_asserteq(0, run_command("setexpr.s fred 0", 0)); + ut_asserteq_str("0", env_get("fred")); ut_assertok(ut_check_delta(start_mem));
ut_assertok(env_set("fred", "12345")); @@ -335,6 +336,10 @@ static int setexpr_test_str_oper(struct unit_test_state *uts) ulong start_mem; char *buf;
+ /* Test concatenation of strings */ + ut_assertok(run_command("setexpr.s fred '1' + '3'", 0)); + ut_asserteq_str("13", env_get("fred")); + buf = map_sysmem(0, BUF_SIZE); memset(buf, '\xff', BUF_SIZE); strcpy(buf, "hello");

On Sun, Jan 05, 2025 at 11:46:14AM +0100, Heinrich Schuchardt wrote:
The setexpr.s command allows to concatenate two strings.
According to the description in doc/usage/cmd/setexpr.rst the parameters value1 and value2 can be either direct values or pointers to a memory location holding the values.
Unfortunately `setexpr.s <value1> + <value2>` fails if any of the values is a direct value. $? is set to false.
- Add support for direct values in setexpr.s.
- Correct the unit test for "setexpr.s fred 0".
- Add a new unit test for "setexpr.s fred '1' + '3'" giving '13'.
Signed-off-by: Heinrich Schuchardt heinrich.schuchardt@canonical.com
This causes ut_setexpr_setexpr_test_str to fail.
participants (2)
-
Heinrich Schuchardt
-
Tom Rini