git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v6 00/11] Fix icase grep on non-ascii

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Feb 6, 2016, 02:02 UTC
Message-ID
<1454724190-14063-1-git-send-email-pclouds@gmail.com>
In-Reply-To
<1453982183-24124-1-git-send-email-pclouds@gmail.com>

v6 fixes comments from Ramsay and Eric. Interdiff below. The only thing to add is, I decided not to replace !icase_non_ascii with icase_ascii_only. I went with spelling out "!icase || ascii_only". I think it expresses the intention better.

diff --git a/grep.c b/grep.c
index 2e4f71d..aed4fe0 100644
--- a/grep.c
+++ b/grep.c
@@ -412,11 +412,11 @@ static void compile_fixed_regexp(struct grep_pat *p, struct grep_opt *opt)
 	basic_regex_quote_buf(&sb, p->pattern);
 	err = regcomp(&p->regexp, sb.buf, opt->regflags & ~REG_EXTENDED);
 	if (opt->debug)
-		fprintf(stderr, "fixed%s\n", sb.buf);
+		fprintf(stderr, "fixed %s\n", sb.buf);
 	strbuf_release(&sb);
 	if (err) {
 		char errbuf[1024];
-		regerror(err, &p->regexp, errbuf, 1024);
+		regerror(err, &p->regexp, errbuf, sizeof(errbuf));
 		regfree(&p->regexp);
 		compile_regexp_failed(p, errbuf);
 	}
@@ -424,19 +424,18 @@ static void compile_fixed_regexp(struct grep_pat *p, struct grep_opt *opt)
 
 static void compile_regexp(struct grep_pat *p, struct grep_opt *opt)
 {
-	int icase_non_ascii;
+	int icase, ascii_only;
 	int err;
 
 	p->word_regexp = opt->word_regexp;
 	p->ignore_case = opt->ignore_case;
-	icase_non_ascii =
-		(opt->regflags & REG_ICASE || p->ignore_case) &&
-		has_non_ascii(p->pattern);
+	icase	       = opt->regflags & REG_ICASE || p->ignore_case;
+	ascii_only     = !has_non_ascii(p->pattern);
 
-	if (!icase_non_ascii && is_fixed(p->pattern, p->patternlen))
+	if ((!icase || ascii_only) && is_fixed(p->pattern, p->patternlen))
 		p->fixed = 1;
 	else if (opt->fixed) {
-		p->fixed = !icase_non_ascii;
+		p->fixed = !icase || ascii_only;
 		if (!p->fixed) {
 			compile_fixed_regexp(p, opt);
 			return;
diff --git a/t/t0070-fundamental.sh b/t/t0070-fundamental.sh
index 5ed69a6..991ed2a 100755
--- a/t/t0070-fundamental.sh
+++ b/t/t0070-fundamental.sh
@@ -31,7 +31,7 @@ test_expect_success 'git_mkstemps_mode does not fail if fd 0 is not open' '
 
 test_expect_success 'check for a bug in the regex routines' '
 	# if this test fails, re-build git with NO_REGEX=1
-	test-regex
+	test-regex --bug
 '
 
 test_done
diff --git a/t/t7812-grep-icase-non-ascii.sh b/t/t7812-grep-icase-non-ascii.sh
index a5475bb..4176625 100755
--- a/t/t7812-grep-icase-non-ascii.sh
+++ b/t/t7812-grep-icase-non-ascii.sh
@@ -38,12 +38,12 @@ test_expect_success GETTEXT_LOCALE,LIBPCRE 'grep pcre utf-8 string with "+"' '
 test_expect_success REGEX_LOCALE 'grep literal string, with -F' '
 	git grep --debug -i -F "TILRAUN: Halló Heimur!"  2>&1 >/dev/null |
 		 grep fixed >debug1 &&
-	echo "fixedTILRAUN: Halló Heimur!" >expect1 &&
+	echo "fixed TILRAUN: Halló Heimur!" >expect1 &&
 	test_cmp expect1 debug1 &&
 
 	git grep --debug -i -F "TILRAUN: HALLÓ HEIMUR!"  2>&1 >/dev/null |
 		 grep fixed >debug2 &&
-	echo "fixedTILRAUN: HALLÓ HEIMUR!" >expect2 &&
+	echo "fixed TILRAUN: HALLÓ HEIMUR!" >expect2 &&
 	test_cmp expect2 debug2
 '
 
@@ -52,12 +52,12 @@ test_expect_success REGEX_LOCALE 'grep string with regex, with -F' '
 
 	git grep --debug -i -F "^*TILR^AUN:.* \\Halló \$He[]imur!\$" 2>&1 >/dev/null |
 		 grep fixed >debug1 &&
-	echo "fixed\\^*TILR^AUN:\\.\\* \\\\Halló \$He\\[]imur!\\\$" >expect1 &&
+	echo "fixed \\^*TILR^AUN:\\.\\* \\\\Halló \$He\\[]imur!\\\$" >expect1 &&
 	test_cmp expect1 debug1 &&
 
 	git grep --debug -i -F "^*TILR^AUN:.* \\HALLÓ \$HE[]IMUR!\$"  2>&1 >/dev/null |
 		 grep fixed >debug2 &&
-	echo "fixed\\^*TILR^AUN:\\.\\* \\\\HALLÓ \$HE\\[]IMUR!\\\$" >expect2 &&
+	echo "fixed \\^*TILR^AUN:\\.\\* \\\\HALLÓ \$HE\\[]IMUR!\\\$" >expect2 &&
 	test_cmp expect2 debug2
 '
 
diff --git a/test-regex.c b/test-regex.c
index 3b5641c..d1a952c 100644
--- a/test-regex.c
+++ b/test-regex.c
@@ -17,6 +17,25 @@ static struct reg_flag reg_flags[] = {
 	{ NULL, 0 }
 };
 
+static int test_regex_bug(void)
+{
+	char *pat = "[^={} \t]+";
+	char *str = "={}\nfred";
+	regex_t r;
+	regmatch_t m[1];
+
+	if (regcomp(&r, pat, REG_EXTENDED | REG_NEWLINE))
+		die("failed regcomp() for pattern '%s'", pat);
+	if (regexec(&r, str, 1, m, 0))
+		die("no match of pattern '%s' to string '%s'", pat, str);
+
+	/* http://sourceware.org/bugzilla/show_bug.cgi?id=3957  */
+	if (m[0].rm_so == 3) /* matches '\n' when it should not */
+		die("regex bug confirmed: re-build git with NO_REGEX=1");
+
+	return 0;
+}
+
 int main(int argc, char **argv)
 {
 	const char *pat;
@@ -25,40 +44,32 @@ int main(int argc, char **argv)
 	regex_t r;
 	regmatch_t m[1];
 
-	if (argc == 1) {
-		/* special case, bug check */
-		pat = "[^={} \t]+";
-		str = "={}\nfred";
-		flags = REG_EXTENDED | REG_NEWLINE;
-	} else {
+	if (argc == 2 && !strcmp(argv[1], "--bug"))
+		return test_regex_bug();
+	else if (argc < 3)
+		die("usage: test-regex --bug\n"
+		    "       test-regex <pattern> <string> [<options>]");
+
+	argv++;
+	pat = *argv++;
+	str = *argv++;
+	while (*argv) {
+		struct reg_flag *rf;
+		for (rf = reg_flags; rf->name; rf++)
+			if (!strcmp(*argv, rf->name)) {
+				flags |= rf->flag;
+				break;
+			}
+		if (!rf->name)
+			die("do not recognize %s", *argv);
 		argv++;
-		pat = *argv++;
-		str = *argv++;
-		while (*argv) {
-			struct reg_flag *rf;
-			for (rf = reg_flags; rf->name; rf++)
-				if (!strcmp(*argv, rf->name)) {
-					flags |= rf->flag;
-					break;
-				}
-			if (!rf->name)
-				die("do not recognize %s", *argv);
-			argv++;
-		}
-		git_setup_gettext();
 	}
+	git_setup_gettext();
 
 	if (regcomp(&r, pat, flags))
 		die("failed regcomp() for pattern '%s'", pat);
-	if (regexec(&r, str, 1, m, 0)) {
-		if (argc == 1)
-			die("no match of pattern '%s' to string '%s'", pat, str);
+	if (regexec(&r, str, 1, m, 0))
 		return 1;
-	}
-
-	/* http://sourceware.org/bugzilla/show_bug.cgi?id=3957  */
-	if (argc == 1 && m[0].rm_so == 3) /* matches '\n' when it should not */
-		die("regex bug confirmed: re-build git with NO_REGEX=1");
 
-	exit(0);
+	return 0;
 }
-- 
2.7.0.377.g4cd97dd
Previous: Junio C HamanoNext: Nguyễn Thái Ngọc Duy
Message 19 of 56 in “Fix icase grep on non-ascii”
  1. 00/10 Fix icase grep on non-asciiNguyễn Thái Ngọc Duy, Jan 28, 2016
  2. 01/10 grep: allow -F -i combinationNguyễn Thái Ngọc Duy, Jan 28, 2016
  3. 02/10 grep: break down an "if" stmt in preparation for next changesNguyễn Thái Ngọc Duy, Jan 28, 2016
  4. 03/10 test-regex: expose full regcomp() to the command lineNguyễn Thái Ngọc Duy, Jan 28, 2016
  5. Eric SunshineJan 29, 2016
  6. Ramsay JonesJan 29, 2016
  7. 04/10 grep/icase: avoid kwsset on literal non-ascii stringsNguyễn Thái Ngọc Duy, Jan 28, 2016
  8. Eric SunshineJan 29, 2016
  9. Eric SunshineJan 29, 2016
  10. 05/10 grep/icase: avoid kwsset when -F is specifiedNguyễn Thái Ngọc Duy, Jan 28, 2016
  11. Eric SunshineJan 29, 2016
  12. 06/10 grep/pcre: prepare locale-dependent tables for icase matchingNguyễn Thái Ngọc Duy, Jan 28, 2016
  13. 07/10 gettext: add is_utf8_locale()Nguyễn Thái Ngọc Duy, Jan 28, 2016
  14. 08/10 grep/pcre: support utf-8Nguyễn Thái Ngọc Duy, Jan 28, 2016
  15. 09/10 diffcore-pickaxe: "share" regex error handling codeNguyễn Thái Ngọc Duy, Jan 28, 2016
  16. 10/10 diffcore-pickaxe: support case insensitive match on non-asciiNguyễn Thái Ngọc Duy, Jan 28, 2016
  17. Eric SunshineJan 29, 2016
  18. Junio C HamanoJan 28, 2016
  19. 00/11 Fix icase grep on non-asciiNguyễn Thái Ngọc Duy, Feb 6, 2016
  20. 01/11 grep: allow -F -i combinationNguyễn Thái Ngọc Duy, Feb 6, 2016
  21. Junio C HamanoJun 17, 2016
  22. Duy NguyenJun 18, 2016
  23. 02/11 grep: break down an "if" stmt in preparation for next changesNguyễn Thái Ngọc Duy, Feb 6, 2016
  24. Junio C HamanoFeb 9, 2016
  25. 03/11 test-regex: isolate the bug test codeNguyễn Thái Ngọc Duy, Feb 6, 2016
  26. 04/11 test-regex: expose full regcomp() to the command lineNguyễn Thái Ngọc Duy, Feb 6, 2016
  27. Eric SunshineFeb 7, 2016
  28. Junio C HamanoFeb 9, 2016
  29. 05/11 grep/icase: avoid kwsset on literal non-ascii stringsNguyễn Thái Ngọc Duy, Feb 6, 2016
  30. 06/11 grep/icase: avoid kwsset when -F is specifiedNguyễn Thái Ngọc Duy, Feb 6, 2016
  31. 07/11 grep/pcre: prepare locale-dependent tables for icase matchingNguyễn Thái Ngọc Duy, Feb 6, 2016
  32. 08/11 gettext: add is_utf8_locale()Nguyễn Thái Ngọc Duy, Feb 6, 2016
  33. 09/11 grep/pcre: support utf-8Nguyễn Thái Ngọc Duy, Feb 6, 2016
  34. 10/11 diffcore-pickaxe: "share" regex error handling codeNguyễn Thái Ngọc Duy, Feb 6, 2016
  35. 11/11 diffcore-pickaxe: support case insensitive match on non-asciiNguyễn Thái Ngọc Duy, Feb 6, 2016
  36. Eric SunshineFeb 7, 2016
  37. 00/12 nd/icase updatesNguyễn Thái Ngọc Duy, Feb 14, 2016
  38. 01/12 grep: allow -F -i combinationNguyễn Thái Ngọc Duy, Feb 14, 2016
  39. 02/12 grep: break down an "if" stmt in preparation for next changesNguyễn Thái Ngọc Duy, Feb 14, 2016
  40. 03/12 test-regex: isolate the bug test codeNguyễn Thái Ngọc Duy, Feb 14, 2016
  41. 04/12 test-regex: expose full regcomp() to the command lineNguyễn Thái Ngọc Duy, Feb 14, 2016
  42. 05/12 grep/icase: avoid kwsset on literal non-ascii stringsNguyễn Thái Ngọc Duy, Feb 14, 2016
  43. 06/12 grep/icase: avoid kwsset when -F is specifiedNguyễn Thái Ngọc Duy, Feb 14, 2016
  44. 07/12 grep/pcre: prepare locale-dependent tables for icase matchingNguyễn Thái Ngọc Duy, Feb 14, 2016
  45. 08/12 gettext: add is_utf8_locale()Nguyễn Thái Ngọc Duy, Feb 14, 2016
  46. 09/12 grep/pcre: support utf-8Nguyễn Thái Ngọc Duy, Feb 14, 2016
  47. 10/12 diffcore-pickaxe: "share" regex error handling codeNguyễn Thái Ngọc Duy, Feb 14, 2016
  48. 11/12 diffcore-pickaxe: support case insensitive match on non-asciiNguyễn Thái Ngọc Duy, Feb 14, 2016
  49. 12/12 grep.c: reuse "icase" variableNguyễn Thái Ngọc Duy, Feb 14, 2016
  50. Junio C HamanoJun 17, 2016
  51. Duy NguyenJun 18, 2016
  52. Duy NguyenJun 22, 2016
  53. Junio C HamanoJun 22, 2016
  54. Duy NguyenJun 22, 2016
  55. Junio C HamanoJun 22, 2016
  56. Junio C HamanoJun 22, 2016

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.