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 <massimiliano.minella@se.com>
This commit is contained in:
Massimiliano Minella 2024-02-08 15:58:27 +01:00 committed by Tom Rini
parent fd50ae3f26
commit 4c73630686
3 changed files with 15 additions and 5 deletions

View File

@ -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 <r> in the\n"
" string <t>, substitute the string <s>. The result is\n"
" assigned to <name>. If <t> is not supplied, use the old\n"
" value of <name>\n"
" value of <name>. If no substring matching <r> is found in <t>,\n"
" assign <t> to <name>.\n"
"setexpr name sub r s [t]\n"
" - Just like gsub(), but replace only the first matching substring"
#endif

View File

@ -39,6 +39,7 @@ setexpr name gsub <r> <s> [<t>]
string <t>, substitute the string <s>.
The result is assigned to <name>.
If <t> is not supplied, use the old value of <name>.
If no substring matching <r> is found in <t>, assign <t> to <name>.
setexpr name sub <r> <s> [<t>]
Just like gsub(), but replace only the first matching substring

View File

@ -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;