From 90a9901764d71308192c96ecd7d735531fe9cc30 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 1 Nov 2020 14:15:35 -0700 Subject: test: Add some tests for setexpr This command currently has no tests. Add some for basic assignment and the integer operations. Note that the default size for setexpr is ulong, which varies depending on the build machine. So for sandbox on a 64-bit host, this means that the default size is 64 bits. Signed-off-by: Simon Glass --- test/cmd/setexpr.c | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 test/cmd/setexpr.c (limited to 'test/cmd/setexpr.c') diff --git a/test/cmd/setexpr.c b/test/cmd/setexpr.c new file mode 100644 index 00000000000..cab6fdf4b83 --- /dev/null +++ b/test/cmd/setexpr.c @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Tests for setexpr command + * + * Copyright 2020 Google LLC + * Written by Simon Glass + */ + +#include +#include +#include +#include +#include +#include + +#define BUF_SIZE 0x100 + +/* Declare a new mem test */ +#define SETEXPR_TEST(_name, _flags) UNIT_TEST(_name, _flags, setexpr_test) + +/* Test 'setexpr' command with simply setting integers */ +static int setexpr_test_int(struct unit_test_state *uts) +{ + u8 *buf; + + buf = map_sysmem(0, BUF_SIZE); + memset(buf, '\xff', BUF_SIZE); + + /* byte */ + buf[0x0] = 0x12; + ut_assertok(run_command("setexpr.b fred 0", 0)); + ut_asserteq_str("0", env_get("fred")); + ut_assertok(run_command("setexpr.b fred *0", 0)); + ut_asserteq_str("12", env_get("fred")); + + /* 16-bit */ + *(short *)buf = 0x2345; + ut_assertok(run_command("setexpr.w fred 0", 0)); + ut_asserteq_str("0", env_get("fred")); + ut_assertok(run_command("setexpr.w fred *0", 0)); + ut_asserteq_str("2345", env_get("fred")); + + /* 32-bit */ + *(u32 *)buf = 0x3456789a; + ut_assertok(run_command("setexpr.l fred 0", 0)); + ut_asserteq_str("0", env_get("fred")); + ut_assertok(run_command("setexpr.l fred *0", 0)); + ut_asserteq_str("ffffffff3456789a", env_get("fred")); + + /* 64-bit */ + *(u64 *)buf = 0x456789abcdef0123; + ut_assertok(run_command("setexpr.q fred 0", 0)); + ut_asserteq_str("0", env_get("fred")); + ut_assertok(run_command("setexpr.q fred *0", 0)); + ut_asserteq_str("456789abcdef0123", env_get("fred")); + + /* default */ + ut_assertok(run_command("setexpr fred 0", 0)); + ut_asserteq_str("0", env_get("fred")); + ut_assertok(run_command("setexpr fred *0", 0)); + ut_asserteq_str("456789abcdef0123", env_get("fred")); + + unmap_sysmem(buf); + + return 0; +} +SETEXPR_TEST(setexpr_test_int, UT_TESTF_CONSOLE_REC); + +/* Test 'setexpr' command with + operator */ +static int setexpr_test_plus(struct unit_test_state *uts) +{ + char *buf; + + buf = map_sysmem(0, BUF_SIZE); + memset(buf, '\xff', BUF_SIZE); + + /* byte */ + buf[0x0] = 0x12; + buf[0x10] = 0x34; + ut_assertok(run_command("setexpr.b fred *0 + *10", 0)); + ut_asserteq_str("46", env_get("fred")); + + /* 16-bit */ + *(short *)buf = 0x2345; + *(short *)(buf + 0x10) = 0xf012; + ut_assertok(run_command("setexpr.w fred *0 + *10", 0)); + ut_asserteq_str("11357", env_get("fred")); + + /* 32-bit */ + *(u32 *)buf = 0x3456789a; + *(u32 *)(buf + 0x10) = 0xc3384235; + ut_assertok(run_command("setexpr.l fred *0 + *10", 0)); + ut_asserteq_str("fffffffef78ebacf", env_get("fred")); + + /* 64-bit */ + *(u64 *)buf = 0x456789abcdef0123; + *(u64 *)(buf + 0x10) = 0x4987328372849283; + ut_assertok(run_command("setexpr.q fred *0 + *10", 0)); + ut_asserteq_str("8eeebc2f407393a6", env_get("fred")); + + /* default */ + ut_assertok(run_command("setexpr fred *0 + *10", 0)); + ut_asserteq_str("8eeebc2f407393a6", env_get("fred")); + + unmap_sysmem(buf); + + return 0; +} +SETEXPR_TEST(setexpr_test_plus, UT_TESTF_CONSOLE_REC); + +/* Test 'setexpr' command with other operators */ +static int setexpr_test_oper(struct unit_test_state *uts) +{ + char *buf; + + buf = map_sysmem(0, BUF_SIZE); + memset(buf, '\xff', BUF_SIZE); + + *(u32 *)buf = 0x1234; + *(u32 *)(buf + 0x10) = 0x560000; + + /* Quote | to avoid confusing hush */ + ut_assertok(run_command("setexpr fred *0 \"|\" *10", 0)); + ut_asserteq_str("ffffffff00561234", env_get("fred")); + + *(u32 *)buf = 0x561200; + *(u32 *)(buf + 0x10) = 0x1234; + + /* Quote & to avoid confusing hush */ + ut_assertok(run_command("setexpr.l fred *0 \"&\" *10", 0)); + ut_asserteq_str("ffffffff00001200", env_get("fred")); + + ut_assertok(run_command("setexpr.l fred *0 ^ *10", 0)); + ut_asserteq_str("560034", env_get("fred")); + + ut_assertok(run_command("setexpr.l fred *0 - *10", 0)); + ut_asserteq_str("55ffcc", env_get("fred")); + + ut_assertok(run_command("setexpr.l fred *0 * *10", 0)); + ut_asserteq_str("ffa9dbd21ebfa800", env_get("fred")); + + ut_assertok(run_command("setexpr.l fred *0 / *10", 0)); + ut_asserteq_str("1", env_get("fred")); + + ut_assertok(run_command("setexpr.l fred *0 % *10", 0)); + ut_asserteq_str("55ffcc", env_get("fred")); + + unmap_sysmem(buf); + + return 0; +} +SETEXPR_TEST(setexpr_test_oper, UT_TESTF_CONSOLE_REC); + +int do_ut_setexpr(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + struct unit_test *tests = ll_entry_start(struct unit_test, + setexpr_test); + const int n_ents = ll_entry_count(struct unit_test, setexpr_test); + + return cmd_ut_category("cmd_setexpr", "cmd_mem_", tests, n_ents, argc, + argv); +} -- cgit v1.2.3 From 25a43ac84a9509b8ccd093808bb39b71e4438cf5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 1 Nov 2020 14:15:37 -0700 Subject: setexpr: Add explicit support for 32- and 64-bit ints At present this function assumes that a size of 4 refers to a ulong. This is true on 32-bit machines but not commonly on 64-bit machines. This means that the 'l' specify does not work correctly with setexpr. Add an explicit case for 32-bit values so that 64-bit machines can still use the 'l' specifier. On 32-bit machines, 64-bit is still not supported. This corrects the operation of the default size (which is 4 for setexpr), so update the tests accordingly. The original code for reading from memory was included in 47ab5ad1457 ("cmd_setexpr: allow memory addresses in expressions") but I am not adding a Fixes: tag since that code was not written with 64-bit machines in mind. Signed-off-by: Simon Glass --- test/cmd/setexpr.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'test/cmd/setexpr.c') diff --git a/test/cmd/setexpr.c b/test/cmd/setexpr.c index cab6fdf4b83..e950c380ce0 100644 --- a/test/cmd/setexpr.c +++ b/test/cmd/setexpr.c @@ -45,7 +45,7 @@ static int setexpr_test_int(struct unit_test_state *uts) ut_assertok(run_command("setexpr.l fred 0", 0)); ut_asserteq_str("0", env_get("fred")); ut_assertok(run_command("setexpr.l fred *0", 0)); - ut_asserteq_str("ffffffff3456789a", env_get("fred")); + ut_asserteq_str("3456789a", env_get("fred")); /* 64-bit */ *(u64 *)buf = 0x456789abcdef0123; @@ -58,7 +58,7 @@ static int setexpr_test_int(struct unit_test_state *uts) ut_assertok(run_command("setexpr fred 0", 0)); ut_asserteq_str("0", env_get("fred")); ut_assertok(run_command("setexpr fred *0", 0)); - ut_asserteq_str("456789abcdef0123", env_get("fred")); + ut_asserteq_str("cdef0123", env_get("fred")); unmap_sysmem(buf); @@ -90,7 +90,7 @@ static int setexpr_test_plus(struct unit_test_state *uts) *(u32 *)buf = 0x3456789a; *(u32 *)(buf + 0x10) = 0xc3384235; ut_assertok(run_command("setexpr.l fred *0 + *10", 0)); - ut_asserteq_str("fffffffef78ebacf", env_get("fred")); + ut_asserteq_str("f78ebacf", env_get("fred")); /* 64-bit */ *(u64 *)buf = 0x456789abcdef0123; @@ -100,7 +100,7 @@ static int setexpr_test_plus(struct unit_test_state *uts) /* default */ ut_assertok(run_command("setexpr fred *0 + *10", 0)); - ut_asserteq_str("8eeebc2f407393a6", env_get("fred")); + ut_asserteq_str("1407393a6", env_get("fred")); unmap_sysmem(buf); @@ -121,14 +121,14 @@ static int setexpr_test_oper(struct unit_test_state *uts) /* Quote | to avoid confusing hush */ ut_assertok(run_command("setexpr fred *0 \"|\" *10", 0)); - ut_asserteq_str("ffffffff00561234", env_get("fred")); + ut_asserteq_str("561234", env_get("fred")); *(u32 *)buf = 0x561200; *(u32 *)(buf + 0x10) = 0x1234; /* Quote & to avoid confusing hush */ ut_assertok(run_command("setexpr.l fred *0 \"&\" *10", 0)); - ut_asserteq_str("ffffffff00001200", env_get("fred")); + ut_asserteq_str("1200", env_get("fred")); ut_assertok(run_command("setexpr.l fred *0 ^ *10", 0)); ut_asserteq_str("560034", env_get("fred")); @@ -137,13 +137,13 @@ static int setexpr_test_oper(struct unit_test_state *uts) ut_asserteq_str("55ffcc", env_get("fred")); ut_assertok(run_command("setexpr.l fred *0 * *10", 0)); - ut_asserteq_str("ffa9dbd21ebfa800", env_get("fred")); + ut_asserteq_str("61ebfa800", env_get("fred")); ut_assertok(run_command("setexpr.l fred *0 / *10", 0)); - ut_asserteq_str("1", env_get("fred")); + ut_asserteq_str("4ba", env_get("fred")); ut_assertok(run_command("setexpr.l fred *0 % *10", 0)); - ut_asserteq_str("55ffcc", env_get("fred")); + ut_asserteq_str("838", env_get("fred")); unmap_sysmem(buf); -- cgit v1.2.3 From e713124e352efe3141af6a4ffc83f6dba449a177 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 1 Nov 2020 14:15:38 -0700 Subject: test: Add some setexpr regex tests Add tests for the setexpr regex commands. Note that these tests currently crash on sandbox due to an existing bug in the setexpr implementation, so two of the tests are commented out. Signed-off-by: Simon Glass --- test/cmd/setexpr.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) (limited to 'test/cmd/setexpr.c') diff --git a/test/cmd/setexpr.c b/test/cmd/setexpr.c index e950c380ce0..de54561917c 100644 --- a/test/cmd/setexpr.c +++ b/test/cmd/setexpr.c @@ -151,6 +151,64 @@ static int setexpr_test_oper(struct unit_test_state *uts) } SETEXPR_TEST(setexpr_test_oper, UT_TESTF_CONSOLE_REC); +/* Test 'setexpr' command with regex */ +static int setexpr_test_regex(struct unit_test_state *uts) +{ + char *buf, *val; + + buf = map_sysmem(0, BUF_SIZE); + + /* Single substitution */ + ut_assertok(run_command("setenv fred 'this is a test'", 0)); + ut_assertok(run_command("setexpr fred sub is us", 0)); + val = env_get("fred"); + ut_asserteq_str("thus is a test", val); + + /* Global substitution */ + ut_assertok(run_command("setenv fred 'this is a test'", 0)); + if (0) { + /* Causes a crash at present due to a bug in setexpr */ + ut_assertok(run_command("setexpr fred gsub is us", 0)); + val = env_get("fred"); + ut_asserteq_str("thus us a test", val); + } + /* Global substitution */ + ut_assertok(run_command("setenv fred 'this is a test'", 0)); + ut_assertok(run_command("setenv mary 'this is a test'", 0)); + ut_assertok(run_command("setexpr fred gsub is us \"${mary}\"", 0)); + val = env_get("fred"); + ut_asserteq_str("thus us a test", val); + val = env_get("mary"); + ut_asserteq_str("this is a test", val); + + unmap_sysmem(buf); + + return 0; +} +SETEXPR_TEST(setexpr_test_regex, UT_TESTF_CONSOLE_REC); + +/* Test 'setexpr' command with regex replacement that expands the string */ +static int setexpr_test_regex_inc(struct unit_test_state *uts) +{ + char *buf, *val; + + buf = map_sysmem(0, BUF_SIZE); + + ut_assertok(run_command("setenv fred 'this is a test'", 0)); + if (0) { + /* Causes a crash at present due to a bug in setexpr */ + ut_assertok(run_command("setexpr fred gsub is much_longer_string", + 0)); + val = env_get("fred"); + ut_asserteq_str("thmuch_longer_string much_longer_string a test", + val); + } + unmap_sysmem(buf); + + return 0; +} +SETEXPR_TEST(setexpr_test_regex_inc, UT_TESTF_CONSOLE_REC); + int do_ut_setexpr(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { struct unit_test *tests = ll_entry_start(struct unit_test, -- cgit v1.2.3 From d422c77ae8e0cb1211b34eb4af442600b0da8d5b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 1 Nov 2020 14:15:40 -0700 Subject: setexpr: Add some tests for buffer overflow and backref Add tests to check for buffer overflow using simple replacement as well as back references. At present these don't fully pass. Signed-off-by: Simon Glass --- test/cmd/setexpr.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) (limited to 'test/cmd/setexpr.c') diff --git a/test/cmd/setexpr.c b/test/cmd/setexpr.c index de54561917c..a6940fd82dd 100644 --- a/test/cmd/setexpr.c +++ b/test/cmd/setexpr.c @@ -209,6 +209,95 @@ static int setexpr_test_regex_inc(struct unit_test_state *uts) } SETEXPR_TEST(setexpr_test_regex_inc, UT_TESTF_CONSOLE_REC); +/* Test setexpr_regex_sub() directly to check buffer usage */ +static int setexpr_test_sub(struct unit_test_state *uts) +{ + char *buf, *nbuf; + int i; + + buf = map_sysmem(0, BUF_SIZE); + nbuf = map_sysmem(0x1000, BUF_SIZE); + + /* Add a pattern so we can check the buffer limits */ + memset(buf, '\xff', BUF_SIZE); + memset(nbuf, '\xff', BUF_SIZE); + for (i = BUF_SIZE; i < 0x1000; i++) { + buf[i] = i & 0xff; + nbuf[i] = i & 0xff; + } + strcpy(buf, "this is a test"); + + /* + * This is a regression test, since a bug was found in the use of + * memmove() in setexpr + */ + ut_assertok(setexpr_regex_sub(buf, BUF_SIZE, nbuf, BUF_SIZE, "is", + "us it is longer", true)); + ut_asserteq_str("thus it is longer us it is longer a test", buf); + + /* The following checks fail at present due to a bug in setexpr */ + return 0; + for (i = BUF_SIZE; i < 0x1000; i++) { + ut_assertf(buf[i] == (char)i, + "buf byte at %x should be %02x, got %02x)\n", + i, i & 0xff, (u8)buf[i]); + ut_assertf(nbuf[i] == (char)i, + "nbuf byte at %x should be %02x, got %02x)\n", + i, i & 0xff, (u8)nbuf[i]); + } + + unmap_sysmem(buf); + + return 0; +} +SETEXPR_TEST(setexpr_test_sub, UT_TESTF_CONSOLE_REC); + +/* Test setexpr_regex_sub() with back references */ +static int setexpr_test_backref(struct unit_test_state *uts) +{ + char *buf, *nbuf; + int i; + + buf = map_sysmem(0, BUF_SIZE); + nbuf = map_sysmem(0x1000, BUF_SIZE); + + /* Add a pattern so we can check the buffer limits */ + memset(buf, '\xff', BUF_SIZE); + memset(nbuf, '\xff', BUF_SIZE); + for (i = BUF_SIZE; i < 0x1000; i++) { + buf[i] = i & 0xff; + nbuf[i] = i & 0xff; + } + strcpy(buf, "this is surely a test is it? yes this is indeed a test"); + + /* + * This is a regression test, since a bug was found in the use of + * memmove() in setexpr + */ + ut_assertok(setexpr_regex_sub(buf, BUF_SIZE, nbuf, BUF_SIZE, + "(this) (is) (surely|indeed)", + "us \\1 \\2 \\3!", true)); + + /* The following checks fail at present due to bugs in setexpr */ + return 0; + ut_asserteq_str("us this is surely! a test is it? yes us this is indeed! a test", + buf); + + for (i = BUF_SIZE; i < 0x1000; i++) { + ut_assertf(buf[i] == (char)i, + "buf byte at %x should be %02x, got %02x)\n", + i, i & 0xff, (u8)buf[i]); + ut_assertf(nbuf[i] == (char)i, + "nbuf byte at %x should be %02x, got %02x)\n", + i, i & 0xff, (u8)nbuf[i]); + } + + unmap_sysmem(buf); + + return 0; +} +SETEXPR_TEST(setexpr_test_backref, UT_TESTF_CONSOLE_REC); + int do_ut_setexpr(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { struct unit_test *tests = ll_entry_start(struct unit_test, -- cgit v1.2.3 From 9528229f22b590cc4b5cf8bf0d3212d2ab08ffd5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 1 Nov 2020 14:15:41 -0700 Subject: setexpr: Correct dropping of final unmatched string At present the 'nlen' variable increases with each loop. If the previous loop had back references, then subsequent loops without back references use the wrong value of nlen. The value is larger, meaning that the string terminator from nbuf is copied along to the main buffer, thus terminating the string prematurely. This leads to the final result being truncated, e.g. missing the last (unmatched) part of the string. So "match match tail" become "replaced replaced" instead of "replaced replaced tail". Fix this by resetting nlen to the correct value each time around the lop. Fixes: 855f18ea0e6 ("setexpr: add regex substring matching and substitution") Signed-off-by: Simon Glass --- test/cmd/setexpr.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'test/cmd/setexpr.c') diff --git a/test/cmd/setexpr.c b/test/cmd/setexpr.c index a6940fd82dd..d06dda260e6 100644 --- a/test/cmd/setexpr.c +++ b/test/cmd/setexpr.c @@ -277,12 +277,11 @@ static int setexpr_test_backref(struct unit_test_state *uts) ut_assertok(setexpr_regex_sub(buf, BUF_SIZE, nbuf, BUF_SIZE, "(this) (is) (surely|indeed)", "us \\1 \\2 \\3!", true)); - - /* The following checks fail at present due to bugs in setexpr */ - return 0; ut_asserteq_str("us this is surely! a test is it? yes us this is indeed! a test", buf); + /* The following checks fail at present due to a bug in setexpr */ + return 0; for (i = BUF_SIZE; i < 0x1000; i++) { ut_assertf(buf[i] == (char)i, "buf byte at %x should be %02x, got %02x)\n", -- cgit v1.2.3 From 8f4aa7ddb908369db971d4c31850ca1eef2e3687 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 1 Nov 2020 14:15:42 -0700 Subject: setexpr: Correct buffer overflow bug and enable tests At present when more than one substitution is made this function overwrites its buffers. Fix this bug and update the tests now that they can pass. Also update the debug code to show all substrings, since at present it omits the final one. Fixes: 855f18ea0e6 ("setexpr: add regex substring matching and substitution") Signed-off-by: Simon Glass --- test/cmd/setexpr.c | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) (limited to 'test/cmd/setexpr.c') diff --git a/test/cmd/setexpr.c b/test/cmd/setexpr.c index d06dda260e6..2a897efd9bd 100644 --- a/test/cmd/setexpr.c +++ b/test/cmd/setexpr.c @@ -166,12 +166,10 @@ static int setexpr_test_regex(struct unit_test_state *uts) /* Global substitution */ ut_assertok(run_command("setenv fred 'this is a test'", 0)); - if (0) { - /* Causes a crash at present due to a bug in setexpr */ - ut_assertok(run_command("setexpr fred gsub is us", 0)); - val = env_get("fred"); - ut_asserteq_str("thus us a test", val); - } + ut_assertok(run_command("setexpr fred gsub is us", 0)); + val = env_get("fred"); + ut_asserteq_str("thus us a test", val); + /* Global substitution */ ut_assertok(run_command("setenv fred 'this is a test'", 0)); ut_assertok(run_command("setenv mary 'this is a test'", 0)); @@ -195,14 +193,9 @@ static int setexpr_test_regex_inc(struct unit_test_state *uts) buf = map_sysmem(0, BUF_SIZE); ut_assertok(run_command("setenv fred 'this is a test'", 0)); - if (0) { - /* Causes a crash at present due to a bug in setexpr */ - ut_assertok(run_command("setexpr fred gsub is much_longer_string", - 0)); - val = env_get("fred"); - ut_asserteq_str("thmuch_longer_string much_longer_string a test", - val); - } + ut_assertok(run_command("setexpr fred gsub is much_longer_string", 0)); + val = env_get("fred"); + ut_asserteq_str("thmuch_longer_string much_longer_string a test", val); unmap_sysmem(buf); return 0; @@ -234,9 +227,6 @@ static int setexpr_test_sub(struct unit_test_state *uts) ut_assertok(setexpr_regex_sub(buf, BUF_SIZE, nbuf, BUF_SIZE, "is", "us it is longer", true)); ut_asserteq_str("thus it is longer us it is longer a test", buf); - - /* The following checks fail at present due to a bug in setexpr */ - return 0; for (i = BUF_SIZE; i < 0x1000; i++) { ut_assertf(buf[i] == (char)i, "buf byte at %x should be %02x, got %02x)\n", -- cgit v1.2.3 From 2c02152a8e2d640fe1d93177fbf523d25cd3e8f9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 1 Nov 2020 14:15:44 -0700 Subject: setexpr: Add support for strings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for dealing with string operands, including reading a string from memory into an environment variable and concatenating two strings. Signed-off-by: Simon Glass Acked-by: Marek BehĂșn --- test/cmd/setexpr.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) (limited to 'test/cmd/setexpr.c') diff --git a/test/cmd/setexpr.c b/test/cmd/setexpr.c index 2a897efd9bd..fd6d869c0ed 100644 --- a/test/cmd/setexpr.c +++ b/test/cmd/setexpr.c @@ -287,6 +287,92 @@ static int setexpr_test_backref(struct unit_test_state *uts) } SETEXPR_TEST(setexpr_test_backref, UT_TESTF_CONSOLE_REC); +/* Test 'setexpr' command with setting strings */ +static int setexpr_test_str(struct unit_test_state *uts) +{ + ulong start_mem; + char *buf; + + buf = map_sysmem(0, BUF_SIZE); + memset(buf, '\xff', BUF_SIZE); + + /* + * Set 'fred' to the same length as we expect to get below, to avoid a + * new allocation in 'setexpr'. That way we can check for memory leaks. + */ + 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_assertok(ut_check_delta(start_mem)); + + start_mem = ut_check_free(); + ut_assertok(env_set("fred", "12345")); + ut_assertok(run_command("setexpr.s fred *0", 0)); + ut_asserteq_str("hello", env_get("fred")); + ut_assertok(ut_check_delta(start_mem)); + + unmap_sysmem(buf); + + return 0; +} +SETEXPR_TEST(setexpr_test_str, UT_TESTF_CONSOLE_REC); + + +/* Test 'setexpr' command with concatenating strings */ +static int setexpr_test_str_oper(struct unit_test_state *uts) +{ + ulong start_mem; + char *buf; + + buf = map_sysmem(0, BUF_SIZE); + memset(buf, '\xff', BUF_SIZE); + strcpy(buf, "hello"); + strcpy(buf + 0x10, " there"); + + ut_assertok(console_record_reset_enable()); + start_mem = ut_check_free(); + ut_asserteq(1, run_command("setexpr.s fred *0 * *10", 0)); + ut_assertok(ut_check_delta(start_mem)); + ut_assert_nextline("invalid op"); + ut_assert_console_end(); + + /* + * Set 'fred' to the same length as we expect to get below, to avoid a + * new allocation in 'setexpr'. That way we can check for memory leaks. + */ + ut_assertok(env_set("fred", "12345012345")); + start_mem = ut_check_free(); + ut_assertok(run_command("setexpr.s fred *0 + *10", 0)); + ut_asserteq_str("hello there", env_get("fred")); + ut_assertok(ut_check_delta(start_mem)); + + unmap_sysmem(buf); + + return 0; +} +SETEXPR_TEST(setexpr_test_str_oper, UT_TESTF_CONSOLE_REC); + +/* Test 'setexpr' command with a string that is too long */ +static int setexpr_test_str_long(struct unit_test_state *uts) +{ + const int size = 128 << 10; /* setexpr strings are a max of 64KB */ + char *buf, *val; + + buf = map_sysmem(0, size); + memset(buf, 'a', size); + + /* String should be truncated to 64KB */ + ut_assertok(run_command("setexpr.s fred *0", 0)); + val = env_get("fred"); + ut_asserteq(64 << 10, strlen(val)); + + unmap_sysmem(buf); + + return 0; +} +SETEXPR_TEST(setexpr_test_str_long, UT_TESTF_CONSOLE_REC); + int do_ut_setexpr(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { struct unit_test *tests = ll_entry_start(struct unit_test, -- cgit v1.2.3