Browse Source

tal/str: fix error when strreg regex looks for literal slashes.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Rusty Russell 11 years ago
parent
commit
c8e75cdce1
2 changed files with 28 additions and 2 deletions
  1. 23 1
      ccan/tal/str/str.c
  2. 5 1
      ccan/tal/str/test/run-strreg.c

+ 23 - 1
ccan/tal/str/str.c

@@ -236,9 +236,31 @@ fail:
 	goto out;
 	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, ...)
 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];
 	regmatch_t matches[nmatch];
 	regex_t r;
 	regex_t r;
 	bool ret = false;
 	bool ret = false;

+ 5 - 1
ccan/tal/str/test/run-strreg.c

@@ -21,7 +21,7 @@ int main(int argc, char *argv[])
 	/* If it accesses this, it will crash. */
 	/* If it accesses this, it will crash. */
 	char **invalid = (char **)1L;
 	char **invalid = (char **)1L;
 
 
-	plan_tests(40);
+	plan_tests(41);
 	/* Simple matching. */
 	/* Simple matching. */
 	ok1(tal_strreg(ctx, "hello world!", "hello") == true);
 	ok1(tal_strreg(ctx, "hello world!", "hello") == true);
 	ok1(tal_strreg(ctx, "hello world!", "hi") == false);
 	ok1(tal_strreg(ctx, "hello world!", "hi") == false);
@@ -116,5 +116,9 @@ int main(int argc, char *argv[])
 	ok1(no_children(ctx));
 	ok1(no_children(ctx));
 	tal_free(ctx);
 	tal_free(ctx);
 
 
+	/* Don't get fooled by \(! */
+	ok1(tal_strreg(ctx, "(hello) (world)!", "\\([a-z]*\\) \\([a-z]+\\)",
+		       invalid) == true);
+
 	return exit_status();
 	return exit_status();
 }
 }