]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
slre: fix matching of escape sequence used inside character class
authorRasmus Villemoes <ravi@prevas.dk>
Tue, 13 May 2025 08:40:30 +0000 (10:40 +0200)
committerTom Rini <trini@konsulko.com>
Thu, 29 May 2025 14:25:18 +0000 (08:25 -0600)
At the compile stage, the anyof() function clearly intends to handle escape
sequences like \d (for digits) inside square brackets, since the logic
emits a 0 byte followed by the code representing the character
class (NONSPACE, SPACE or DIGIT).

However, this is not handled in the corresponding match helper
is_any_of(); it just naively loops over all the bytes in the ->data
array emitted by anyof() and compares those directly to the current
character. For example, this means that the string "\x11" (containing
the single character with value 17) is matched by the regex "[#%\d]",
because DIGIT happens to be 17.

Fix that by recognizing a zero byte as indicating something special
and act accordingly. In order not to repeat the "increment *ofs and
return 1" in all places, put those two lines after a new match: label.

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Rasmus Villemoes <ravi@prevas.dk>
lib/slre.c

index 5cb0d3ec7facefa12e7c94572b0cbb92a6f39996..87dfde720e99979c491dcc29a64f09375af5184a 100644 (file)
@@ -472,13 +472,33 @@ is_any_of(const unsigned char *p, int len, const char *s, int *ofs)
 
        ch = s[*ofs];
 
-       for (i = 0; i < len; i++)
-               if (p[i] == ch) {
-                       (*ofs)++;
-                       return 1;
+       for (i = 0; i < len; i++) {
+               if (p[i] == '\0') {
+                       switch (p[++i]) {
+                       case NONSPACE:
+                               if (!isspace(ch))
+                                       goto match;
+                               break;
+                       case SPACE:
+                               if (isspace(ch))
+                                       goto match;
+                               break;
+                       case DIGIT:
+                               if (isdigit(ch))
+                                       goto match;
+                               break;
+                       }
+                       continue;
                }
+               if (p[i] == ch)
+                       goto match;
+       }
 
        return 0;
+
+match:
+       (*ofs)++;
+       return 1;
 }
 
 static int