Skip to content

Commit 1e3f6b6

Browse files
author
Linus Torvalds
committed
git-apply: more consistency checks on gitdiff filenames
There's some duplication of filenames when doing filename operations (creates, deletes, renames and copies), and this makes us verify that the pathnames match when they should.
1 parent 587e494 commit 1e3f6b6

File tree

1 file changed

+46
-4
lines changed

1 file changed

+46
-4
lines changed

apply.c

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,17 +188,59 @@ static int gitdiff_hdrend(const char *line)
188188
return -1;
189189
}
190190

191+
/*
192+
* We're anal about diff header consistency, to make
193+
* sure that we don't end up having strange ambiguous
194+
* patches floating around.
195+
*
196+
* As a result, gitdiff_{old|new}name() will check
197+
* their names against any previous information, just
198+
* to make sure..
199+
*/
200+
static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name, const char *oldnew)
201+
{
202+
int len;
203+
const char *name;
204+
205+
if (!orig_name && !isnull)
206+
return find_name(line, NULL, 1, 0);
207+
208+
name = "/dev/null";
209+
len = 9;
210+
if (orig_name) {
211+
name = orig_name;
212+
len = strlen(name);
213+
if (isnull)
214+
die("git-apply: bad git-diff - expected /dev/null, got %s on line %d", name, linenr);
215+
}
216+
217+
if (*name == '/')
218+
goto absolute_path;
219+
220+
for (;;) {
221+
char c = *line++;
222+
if (c == '\n')
223+
break;
224+
if (c != '/')
225+
continue;
226+
absolute_path:
227+
if (memcmp(line, name, len) || line[len] != '\n')
228+
break;
229+
return orig_name;
230+
}
231+
die("git-apply: bad git-diff - inconsistent %s filename on line %d", oldnew, linenr);
232+
return NULL;
233+
}
234+
191235
static int gitdiff_oldname(const char *line)
192236
{
193-
if (!old_name && !is_new)
194-
old_name = find_name(line, NULL, 1, 0);
237+
old_name = gitdiff_verify_name(line, is_new, old_name, "old");
195238
return 0;
196239
}
197240

198241
static int gitdiff_newname(const char *line)
199242
{
200-
if (!new_name && !is_delete)
201-
new_name = find_name(line, NULL, 1, 0);
243+
new_name = gitdiff_verify_name(line, is_delete, new_name, "new");
202244
return 0;
203245
}
204246

0 commit comments

Comments
 (0)