Skip to content

Commit 5c1ebcc

Browse files
pcloudsgitster
authored andcommitted
grep/icase: avoid kwsset on literal non-ascii strings
When we detect the pattern is just a literal string, we avoid heavy regex engine and use fast substring search implemented in kwsset.c. But kws uses git-ctype which is locale-independent so it does not know how to fold case properly outside ascii range. Let regcomp or pcre take care of this case instead. Slower, but accurate. Noticed-by: Plamen Totev <[email protected]> Helped-by: René Scharfe <[email protected]> Helped-by: Eric Sunshine <[email protected]> Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent d8acfe1 commit 5c1ebcc

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

grep.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "xdiff-interface.h"
55
#include "diff.h"
66
#include "diffcore.h"
7+
#include "commit.h"
78

89
static int grep_source_load(struct grep_source *gs);
910
static int grep_source_is_binary(struct grep_source *gs);
@@ -398,14 +399,18 @@ static int is_fixed(const char *s, size_t len)
398399

399400
static void compile_regexp(struct grep_pat *p, struct grep_opt *opt)
400401
{
402+
int icase, ascii_only;
401403
int err;
402404

403405
p->word_regexp = opt->word_regexp;
404406
p->ignore_case = opt->ignore_case;
407+
icase = opt->regflags & REG_ICASE || p->ignore_case;
408+
ascii_only = !has_non_ascii(p->pattern);
405409

406410
if (opt->fixed)
407411
p->fixed = 1;
408-
else if (is_fixed(p->pattern, p->patternlen))
412+
else if ((!icase || ascii_only) &&
413+
is_fixed(p->pattern, p->patternlen))
409414
p->fixed = 1;
410415
else
411416
p->fixed = 0;

t/t7812-grep-icase-non-ascii.sh

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/bin/sh
2+
3+
test_description='grep icase on non-English locales'
4+
5+
. ./lib-gettext.sh
6+
7+
test_expect_success GETTEXT_LOCALE 'setup' '
8+
test_write_lines "TILRAUN: Halló Heimur!" >file &&
9+
git add file &&
10+
LC_ALL="$is_IS_locale" &&
11+
export LC_ALL
12+
'
13+
14+
test_have_prereq GETTEXT_LOCALE &&
15+
test-regex "HALLÓ" "Halló" ICASE &&
16+
test_set_prereq REGEX_LOCALE
17+
18+
test_expect_success REGEX_LOCALE 'grep literal string, no -F' '
19+
git grep -i "TILRAUN: Halló Heimur!" &&
20+
git grep -i "TILRAUN: HALLÓ HEIMUR!"
21+
'
22+
23+
test_done

0 commit comments

Comments
 (0)