diff options
author | Tom Rini <trini@konsulko.com> | 2025-02-07 13:35:32 -0600 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2025-02-07 13:35:32 -0600 |
commit | ac3dcb0c2710c4917d93d6d2eb34dbfb00516bc2 (patch) | |
tree | af301f49742901d2490ef4563b91fc3b2ceff0b7 /cmd/setexpr.c | |
parent | 7a20c89bd05155675bd9f316c4cffc36961f1070 (diff) | |
parent | af7eca24a78b1419656d618463f1eabe297fdb2f (diff) |
Merge patch series "cmd/setexpr: support concatenation of direct strings"
Heinrich Schuchardt <heinrich.schuchardt@canonical.com> says:
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'.
* Remove invalid memory leak tests
Link: https://lore.kernel.org/r/20250203151029.60265-1-heinrich.schuchardt@canonical.com
Diffstat (limited to 'cmd/setexpr.c')
-rw-r--r-- | cmd/setexpr.c | 54 |
1 files changed, 38 insertions, 16 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; |