mirror of
https://github.com/git/git
synced 2024-08-27 11:39:22 +00:00
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>
This commit is contained in:
parent
4269974179
commit
44e5471a8d
17
apply.c
17
apply.c
|
@ -1011,20 +1011,27 @@ static int gitdiff_newname(struct apply_state *state,
|
||||||
DIFF_NEW_NAME);
|
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,
|
static int gitdiff_oldmode(struct apply_state *state,
|
||||||
const char *line,
|
const char *line,
|
||||||
struct patch *patch)
|
struct patch *patch)
|
||||||
{
|
{
|
||||||
patch->old_mode = strtoul(line, NULL, 8);
|
return parse_mode_line(line, state->linenr, &patch->old_mode);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gitdiff_newmode(struct apply_state *state,
|
static int gitdiff_newmode(struct apply_state *state,
|
||||||
const char *line,
|
const char *line,
|
||||||
struct patch *patch)
|
struct patch *patch)
|
||||||
{
|
{
|
||||||
patch->new_mode = strtoul(line, NULL, 8);
|
return parse_mode_line(line, state->linenr, &patch->new_mode);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gitdiff_delete(struct apply_state *state,
|
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);
|
memcpy(patch->new_sha1_prefix, line, len);
|
||||||
patch->new_sha1_prefix[len] = 0;
|
patch->new_sha1_prefix[len] = 0;
|
||||||
if (*ptr == ' ')
|
if (*ptr == ' ')
|
||||||
patch->old_mode = strtoul(ptr+1, NULL, 8);
|
return gitdiff_oldmode(state, ptr + 1, patch);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,9 @@ test_expect_success setup '
|
||||||
echo modified >file &&
|
echo modified >file &&
|
||||||
git diff --stat -p >patch-0.txt &&
|
git diff --stat -p >patch-0.txt &&
|
||||||
chmod +x file &&
|
chmod +x file &&
|
||||||
git diff --stat -p >patch-1.txt
|
git diff --stat -p >patch-1.txt &&
|
||||||
|
sed "s/^\(new mode \).*/\1/" <patch-1.txt >patch-empty-mode.txt &&
|
||||||
|
sed "s/^\(new mode \).*/\1garbage/" <patch-1.txt >patch-bogus-mode.txt
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success FILEMODE 'same mode (no index)' '
|
test_expect_success FILEMODE 'same mode (no index)' '
|
||||||
|
@ -59,4 +61,16 @@ test_expect_success FILEMODE 'mode update (index only)' '
|
||||||
git ls-files -s file | grep "^100755"
|
git ls-files -s file | grep "^100755"
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success FILEMODE 'empty mode is rejected' '
|
||||||
|
git reset --hard &&
|
||||||
|
test_must_fail git apply patch-empty-mode.txt 2>err &&
|
||||||
|
test_i18ngrep "invalid mode" err
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success FILEMODE 'bogus mode is rejected' '
|
||||||
|
git reset --hard &&
|
||||||
|
test_must_fail git apply patch-bogus-mode.txt 2>err &&
|
||||||
|
test_i18ngrep "invalid mode" err
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
|
Loading…
Reference in a new issue