tal/str: fix error when strreg regex looks for literal slashes.
authorRusty Russell <rusty@rustcorp.com.au>
Mon, 23 Jun 2014 06:36:19 +0000 (16:06 +0930)
committerRusty Russell <rusty@rustcorp.com.au>
Mon, 23 Jun 2014 06:36:19 +0000 (16:06 +0930)
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ccan/tal/str/str.c
ccan/tal/str/test/run-strreg.c

index 237652f738fc2217b5f0e9eeb117f299b2a484b0..059817b6aa7e928b8e9ceeef372e2510b6ebd3f3 100644 (file)
@@ -236,9 +236,31 @@ fail:
        goto out;
 }
 
+static size_t count_open_braces(const char *string)
+{
+#if 1
+       size_t num = 0, esc = 0;
+
+       while (*string) {
+               if (*string == '\\')
+                       esc++;
+               else {
+                       /* An odd number of \ means it's escaped. */
+                       if (*string == '(' && (esc & 1) == 0)
+                               num++;
+                       esc = 0;
+               }
+               string++;
+       }
+       return num;
+#else
+       return strcount(string, "(");
+#endif
+}
+
 bool tal_strreg(const tal_t *ctx, const char *string, const char *regex, ...)
 {
-       size_t nmatch = 1 + strcount(regex, "(");
+       size_t nmatch = 1 + count_open_braces(regex);
        regmatch_t matches[nmatch];
        regex_t r;
        bool ret = false;
index 6d126f3970a13acdbed21cbb63e0115e1aa9d477..fa8a86c66e6127872b1313644e343dc1d05860c2 100644 (file)
@@ -21,7 +21,7 @@ int main(int argc, char *argv[])
        /* If it accesses this, it will crash. */
        char **invalid = (char **)1L;
 
-       plan_tests(40);
+       plan_tests(41);
        /* Simple matching. */
        ok1(tal_strreg(ctx, "hello world!", "hello") == true);
        ok1(tal_strreg(ctx, "hello world!", "hi") == false);
@@ -116,5 +116,9 @@ int main(int argc, char *argv[])
        ok1(no_children(ctx));
        tal_free(ctx);
 
+       /* Don't get fooled by \(! */
+       ok1(tal_strreg(ctx, "(hello) (world)!", "\\([a-z]*\\) \\([a-z]+\\)",
+                      invalid) == true);
+
        return exit_status();
 }