aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-05-23 19:54:55 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-05-23 19:54:55 -0700
commit1e3f6b6e64511491d86ac7ce447ee26cea362d12 (patch)
tree5b09f7ee0529c5cb5e5c06c66ff6385990cc5599
parent587e49405be6c4053a69ee8a938660125aa1b51f (diff)
downloadgit-1e3f6b6e64511491d86ac7ce447ee26cea362d12.tar.gz
git-1e3f6b6e64511491d86ac7ce447ee26cea362d12.tar.xz
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.
-rw-r--r--apply.c50
1 files changed, 46 insertions, 4 deletions
diff --git a/apply.c b/apply.c
index 9dba588f0..251762d21 100644
--- a/apply.c
+++ b/apply.c
@@ -188,17 +188,59 @@ static int gitdiff_hdrend(const char *line)
return -1;
}
+/*
+ * We're anal about diff header consistency, to make
+ * sure that we don't end up having strange ambiguous
+ * patches floating around.
+ *
+ * As a result, gitdiff_{old|new}name() will check
+ * their names against any previous information, just
+ * to make sure..
+ */
+static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name, const char *oldnew)
+{
+ int len;
+ const char *name;
+
+ if (!orig_name && !isnull)
+ return find_name(line, NULL, 1, 0);
+
+ name = "/dev/null";
+ len = 9;
+ if (orig_name) {
+ name = orig_name;
+ len = strlen(name);
+ if (isnull)
+ die("git-apply: bad git-diff - expected /dev/null, got %s on line %d", name, linenr);
+ }
+
+ if (*name == '/')
+ goto absolute_path;
+
+ for (;;) {
+ char c = *line++;
+ if (c == '\n')
+ break;
+ if (c != '/')
+ continue;
+absolute_path:
+ if (memcmp(line, name, len) || line[len] != '\n')
+ break;
+ return orig_name;
+ }
+ die("git-apply: bad git-diff - inconsistent %s filename on line %d", oldnew, linenr);
+ return NULL;
+}
+
static int gitdiff_oldname(const char *line)
{
- if (!old_name && !is_new)
- old_name = find_name(line, NULL, 1, 0);
+ old_name = gitdiff_verify_name(line, is_new, old_name, "old");
return 0;
}
static int gitdiff_newname(const char *line)
{
- if (!new_name && !is_delete)
- new_name = find_name(line, NULL, 1, 0);
+ new_name = gitdiff_verify_name(line, is_delete, new_name, "new");
return 0;
}