setexpr: Correct dropping of final unmatched string
authorSimon Glass <sjg@chromium.org>
Sun, 1 Nov 2020 21:15:41 +0000 (14:15 -0700)
committerTom Rini <trini@konsulko.com>
Tue, 1 Dec 2020 15:33:38 +0000 (10:33 -0500)
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 <sjg@chromium.org>
cmd/setexpr.c
test/cmd/setexpr.c

index dbb43b3be2fad98358eca60464431c36355d2349..0cc7cf15bd7daddfb2c1fede854acb23c5e85ffc 100644 (file)
@@ -147,11 +147,6 @@ int setexpr_regex_sub(char *data, uint data_size, char *nbuf, uint nbuf_size,
        }
 
        len = strlen(data);
-       if (s == NULL)
-               nlen = 0;
-       else
-               nlen = strlen(s);
-
        for (loop = 0;; loop++) {
                struct cap caps[slre.num_caps + 2];
                const char *old;
@@ -187,6 +182,7 @@ int setexpr_regex_sub(char *data, uint data_size, char *nbuf, uint nbuf_size,
 
                old = caps[0].ptr;
                olen = caps[0].len;
+               nlen = strlen(s);
 
                if (nlen + 1 >= nbuf_size) {
                        printf("## error: pattern buffer overflow: have %d, need %d\n",
index a6940fd82dd6e79e06b0c4a2dc8ec21c02a83158..d06dda260e65a1052b45a81c865456dd22ea6569 100644 (file)
@@ -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",