Commit de7659cc by Patrick Steinhardt

patch_parse: use paths from "---"/"+++" lines for binary patches

For some patches, it is not possible to derive the old and new file
paths from the patch header's first line, most importantly when they
contain spaces. In such a case, we derive both paths from the "---" and
"+++" lines, which allow for non-ambiguous parsing. We fail to use these
paths when parsing binary patches without data, though, as we always
expect the header paths to be filled in.

Fix this by using the "---"/"+++" paths by default and only fall back to
header paths if they aren't set. If neither of those paths are set, we
just return an error. Add two tests to verify this behaviour, one of
which would have previously caused a segfault.
parent 01ea911b
......@@ -878,12 +878,18 @@ static int parse_patch_binary_nodata(
git_patch_parsed *patch,
git_patch_parse_ctx *ctx)
{
const char *old = patch->old_path ? patch->old_path : patch->header_old_path;
const char *new = patch->new_path ? patch->new_path : patch->header_new_path;
if (!old || !new)
return git_parse_err("corrupt binary data without paths at line %"PRIuZ, ctx->parse_ctx.line_num);
if (git_parse_advance_expected_str(&ctx->parse_ctx, "Binary files ") < 0 ||
git_parse_advance_expected_str(&ctx->parse_ctx, patch->header_old_path) < 0 ||
git_parse_advance_expected_str(&ctx->parse_ctx, " and ") < 0 ||
git_parse_advance_expected_str(&ctx->parse_ctx, patch->header_new_path) < 0 ||
git_parse_advance_expected_str(&ctx->parse_ctx, " differ") < 0 ||
git_parse_advance_nl(&ctx->parse_ctx) < 0)
git_parse_advance_expected_str(&ctx->parse_ctx, old) < 0 ||
git_parse_advance_expected_str(&ctx->parse_ctx, " and ") < 0 ||
git_parse_advance_expected_str(&ctx->parse_ctx, new) < 0 ||
git_parse_advance_expected_str(&ctx->parse_ctx, " differ") < 0 ||
git_parse_advance_nl(&ctx->parse_ctx) < 0)
return git_parse_err("corrupt git binary header at line %"PRIuZ, ctx->parse_ctx.line_num);
patch->base.binary.contains_data = 0;
......
......@@ -170,6 +170,20 @@ void test_patch_parse__binary_file_with_empty_quoted_paths(void)
strlen(PATCH_BINARY_FILE_WITH_QUOTED_EMPTY_PATHS), NULL));
}
void test_patch_parse__binary_file_path_with_spaces(void)
{
git_patch *patch;
cl_git_fail(git_patch_from_buffer(&patch, PATCH_BINARY_FILE_PATH_WITH_SPACES,
strlen(PATCH_BINARY_FILE_PATH_WITH_SPACES), NULL));
}
void test_patch_parse__binary_file_path_without_body_paths(void)
{
git_patch *patch;
cl_git_fail(git_patch_from_buffer(&patch, PATCH_BINARY_FILE_PATH_WITHOUT_BODY_PATHS,
strlen(PATCH_BINARY_FILE_PATH_WITHOUT_BODY_PATHS), NULL));
}
void test_patch_parse__memory_leak_on_multiple_paths(void)
{
git_patch *patch;
......
......@@ -924,6 +924,18 @@
"+++ \"\"\n" \
"Binary files "
#define PATCH_BINARY_FILE_PATH_WITH_SPACES \
"diff --git a b c d e f\n" \
"--- a b c\n" \
"+++ d e f\n" \
"Binary files a b c and d e f differ"
#define PATCH_BINARY_FILE_PATH_WITHOUT_BODY_PATHS \
"diff --git a b c d e f\n" \
"--- \n" \
"+++ \n" \
"Binary files a b c and d e f differ"
#define PATCH_MULTIPLE_OLD_PATHS \
"diff --git \n" \
"--- \n" \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment