summaryrefslogtreecommitdiff
path: root/apply.c
diff options
context:
space:
mode:
authorRené Scharfe <l.s.r@web.de>2017-06-27 17:03:47 (GMT)
committerJunio C Hamano <gitster@pobox.com>2017-06-27 17:59:38 (GMT)
commit44e5471a8d8ec5f04058220f8b91513b5b5accaa (patch)
tree51047bfed6263f86d712faac43760124249bb6e1 /apply.c
parent4269974179ff4fc2a970c972330ba5b7f26a323b (diff)
downloadgit-44e5471a8d8ec5f04058220f8b91513b5b5accaa.zip
git-44e5471a8d8ec5f04058220f8b91513b5b5accaa.tar.gz
git-44e5471a8d8ec5f04058220f8b91513b5b5accaa.tar.bz2
apply: check git diffs for invalid file modes
An empty string as mode specification is accepted silently by git apply, as Vegard Nossum found out using AFL. It's interpreted as zero. Reject such bogus file modes, and only accept ones consisting exclusively of octal digits. Reported-by: Vegard Nossum <vegard.nossum@oracle.com> Signed-off-by: Rene Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'apply.c')
-rw-r--r--apply.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/apply.c b/apply.c
index 1c0bcd7..4b689d9 100644
--- a/apply.c
+++ b/apply.c
@@ -1011,20 +1011,27 @@ static int gitdiff_newname(struct apply_state *state,
DIFF_NEW_NAME);
}
+static int parse_mode_line(const char *line, int linenr, unsigned int *mode)
+{
+ char *end;
+ *mode = strtoul(line, &end, 8);
+ if (end == line || !isspace(*end))
+ return error(_("invalid mode on line %d: %s"), linenr, line);
+ return 0;
+}
+
static int gitdiff_oldmode(struct apply_state *state,
const char *line,
struct patch *patch)
{
- patch->old_mode = strtoul(line, NULL, 8);
- return 0;
+ return parse_mode_line(line, state->linenr, &patch->old_mode);
}
static int gitdiff_newmode(struct apply_state *state,
const char *line,
struct patch *patch)
{
- patch->new_mode = strtoul(line, NULL, 8);
- return 0;
+ return parse_mode_line(line, state->linenr, &patch->new_mode);
}
static int gitdiff_delete(struct apply_state *state,
@@ -1138,7 +1145,7 @@ static int gitdiff_index(struct apply_state *state,
memcpy(patch->new_sha1_prefix, line, len);
patch->new_sha1_prefix[len] = 0;
if (*ptr == ' ')
- patch->old_mode = strtoul(ptr+1, NULL, 8);
+ return gitdiff_oldmode(state, ptr + 1, patch);
return 0;
}