debian: apply security fixes from 2.24.1
[git/debian.git] / debian / patches / 0015-is_ntfs_dotgit-speed-it-up.diff
blobc7d2ef2dc27a104d184e1dd8c7199e071c1c8745
1 From b281c877c67632aa62fbcaedd07f7981739970fa Mon Sep 17 00:00:00 2001
2 From: Johannes Schindelin <johannes.schindelin@gmx.de>
3 Date: Fri, 6 Sep 2019 21:09:35 +0200
4 Subject: is_ntfs_dotgit(): speed it up
6 Previously, this function was written without focusing on speed,
7 intending to make reviewing the code as easy as possible, to avoid any
8 bugs in this critical code.
10 Turns out: we can do much better on both accounts. With this patch, we
11 make it as fast as this developer can make it go:
13 - We avoid the call to `is_dir_sep()` and make all the character
14 comparisons explicit.
16 - We avoid the cost of calling `strncasecmp()` and unroll the test for
17 `.git` and `git~1`, not even using `tolower()` because it is faster to
18 compare against two constant values.
20 - We look for `.git` and `.git~1` first thing, and return early if not
21 found.
23 - We also avoid calling a separate function for detecting chains of
24 spaces and periods.
26 Each of these improvements has a noticeable impact on the speed of
27 `is_ntfs_dotgit()`.
29 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
30 (cherry picked from commit 3a85dc7d534fc2d410ddc0c771c963b20d1b4857)
31 Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
32 ---
33 path.c | 55 ++++++++++++++++++++++++++++++-------------------------
34 1 file changed, 30 insertions(+), 25 deletions(-)
36 diff --git a/path.c b/path.c
37 index 07d20285e6..e42bba6686 100644
38 --- a/path.c
39 +++ b/path.c
40 @@ -1316,20 +1316,6 @@ int daemon_avoid_alias(const char *p)
44 -static int only_spaces_and_periods(const char *path, size_t len, size_t skip)
46 - if (len < skip)
47 - return 0;
48 - len -= skip;
49 - path += skip;
50 - while (len-- > 0) {
51 - char c = *(path++);
52 - if (c != ' ' && c != '.')
53 - return 0;
54 - }
55 - return 1;
59 * On NTFS, we need to be careful to disallow certain synonyms of the `.git/`
60 * directory:
61 @@ -1369,19 +1355,38 @@ static int only_spaces_and_periods(const char *path, size_t len, size_t skip)
63 int is_ntfs_dotgit(const char *name)
65 - size_t len;
66 + char c;
68 - for (len = 0; ; len++)
69 - if (!name[len] || name[len] == '\\' || is_dir_sep(name[len]) ||
70 - name[len] == ':') {
71 - if (only_spaces_and_periods(name, len, 4) &&
72 - !strncasecmp(name, ".git", 4))
73 - return 1;
74 - if (only_spaces_and_periods(name, len, 5) &&
75 - !strncasecmp(name, "git~1", 5))
76 - return 1;
77 + /*
78 + * Note that when we don't find `.git` or `git~1` we end up with `name`
79 + * advanced partway through the string. That's okay, though, as we
80 + * return immediately in those cases, without looking at `name` any
81 + * further.
82 + */
83 + c = *(name++);
84 + if (c == '.') {
85 + /* .git */
86 + if (((c = *(name++)) != 'g' && c != 'G') ||
87 + ((c = *(name++)) != 'i' && c != 'I') ||
88 + ((c = *(name++)) != 't' && c != 'T'))
89 return 0;
90 - }
91 + } else if (c == 'g' || c == 'G') {
92 + /* git ~1 */
93 + if (((c = *(name++)) != 'i' && c != 'I') ||
94 + ((c = *(name++)) != 't' && c != 'T') ||
95 + *(name++) != '~' ||
96 + *(name++) != '1')
97 + return 0;
98 + } else
99 + return 0;
101 + for (;;) {
102 + c = *(name++);
103 + if (!c || c == '\\' || c == '/' || c == ':')
104 + return 1;
105 + if (c != '.' && c != ' ')
106 + return 0;
110 static int is_ntfs_dot_generic(const char *name,
112 2.24.0.393.g34dc348eaf