From 4c7363068651f222be6150050bb3aa9823ca6f78 Mon Sep 17 00:00:00 2001 From: Massimiliano Minella Date: Thu, 8 Feb 2024 15:58:27 +0100 Subject: [PATCH] cmd: setexpr: fix no matching string in gsub return empty value In gsub, when the destination string is empty, the string 't' is provided and the regular expression doesn't match, then the final result is an empty string. Example: => echo ${foo} => setenv foo => setexpr foo gsub e a bar => echo ${foo} => The variable ${foo} should contain "bar" and the lack of match shouldn't be considered an error. This patch fixes the erroneous behavior by removing the return statement and breaking out of the loop in case of lack of match. Also add a test for the no match case. Signed-off-by: Massimiliano Minella --- cmd/setexpr.c | 9 ++++----- doc/usage/cmd/setexpr.rst | 1 + test/cmd/setexpr.c | 10 ++++++++++ 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/cmd/setexpr.c b/cmd/setexpr.c index 233471f6cb..ab76824a32 100644 --- a/cmd/setexpr.c +++ b/cmd/setexpr.c @@ -216,14 +216,12 @@ int setexpr_regex_sub(char *data, uint data_size, char *nbuf, uint nbuf_size, if (res == 0) { if (loop == 0) { debug("%s: No match\n", data); - return 1; } else { - break; + debug("## MATCH ## %s\n", data); } + break; } - debug("## MATCH ## %s\n", data); - if (!s) return 1; @@ -540,7 +538,8 @@ U_BOOT_CMD( " - For each substring matching the regular expression in the\n" " string , substitute the string . The result is\n" " assigned to . If is not supplied, use the old\n" - " value of \n" + " value of . If no substring matching is found in ,\n" + " assign to .\n" "setexpr name sub r s [t]\n" " - Just like gsub(), but replace only the first matching substring" #endif diff --git a/doc/usage/cmd/setexpr.rst b/doc/usage/cmd/setexpr.rst index d245a13ca8..593a0ea91e 100644 --- a/doc/usage/cmd/setexpr.rst +++ b/doc/usage/cmd/setexpr.rst @@ -39,6 +39,7 @@ setexpr name gsub [] string , substitute the string . The result is assigned to . If is not supplied, use the old value of . + If no substring matching is found in , assign to . setexpr name sub [] Just like gsub(), but replace only the first matching substring diff --git a/test/cmd/setexpr.c b/test/cmd/setexpr.c index 312593e1e3..ee329e94b8 100644 --- a/test/cmd/setexpr.c +++ b/test/cmd/setexpr.c @@ -179,6 +179,16 @@ static int setexpr_test_regex(struct unit_test_state *uts) val = env_get("mary"); ut_asserteq_str("this is a test", val); + /* No match */ + ut_assertok(run_command("setenv fred 'this is a test'", 0)); + ut_assertok(run_command("setenv mary ''", 0)); + ut_assertok(run_command("setexpr fred gsub us is \"${fred}\"", 0)); + ut_assertok(run_command("setexpr mary gsub us is \"${fred}\"", 0)); + val = env_get("fred"); + ut_asserteq_str("this is a test", val); + val = env_get("mary"); + ut_asserteq_str("this is a test", val); + unmap_sysmem(buf); return 0; -- 2.39.5