Commit 048e94adbba3c21b9ad739640cce11a8b387df48

Gregory Herrero 2019-11-07T14:13:14

patch_parse: correct parsing of patch containing not shown binary data. When not shown binary data is added or removed in a patch, patch parser is currently returning 'error -1 - corrupt git binary header at line 4'. Fix it by correctly handling case where binary data is added/removed. Signed-off-by: Gregory Herrero <gregory.herrero@oracle.com>

diff --git a/src/patch_parse.c b/src/patch_parse.c
index e4031f1..87c4b02 100644
--- a/src/patch_parse.c
+++ b/src/patch_parse.c
@@ -231,9 +231,9 @@ static int parse_header_git_deletedfilemode(
 	git_patch_parsed *patch,
 	git_patch_parse_ctx *ctx)
 {
-	git__free((char *)patch->base.delta->old_file.path);
+	git__free((char *)patch->base.delta->new_file.path);
 
-	patch->base.delta->old_file.path = NULL;
+	patch->base.delta->new_file.path = NULL;
 	patch->base.delta->status = GIT_DELTA_DELETED;
 	patch->base.delta->nfiles = 1;
 
@@ -244,9 +244,9 @@ static int parse_header_git_newfilemode(
 	git_patch_parsed *patch,
 	git_patch_parse_ctx *ctx)
 {
-	git__free((char *)patch->base.delta->new_file.path);
+	git__free((char *)patch->base.delta->old_file.path);
 
-	patch->base.delta->new_file.path = NULL;
+	patch->base.delta->old_file.path = NULL;
 	patch->base.delta->status = GIT_DELTA_ADDED;
 	patch->base.delta->nfiles = 1;
 
@@ -884,6 +884,11 @@ static int parse_patch_binary_nodata(
 	if (!old || !new)
 		return git_parse_err("corrupt binary data without paths at line %"PRIuZ, ctx->parse_ctx.line_num);
 
+	if (patch->base.delta->status == GIT_DELTA_ADDED)
+		old = "/dev/null";
+	else if (patch->base.delta->status == GIT_DELTA_DELETED)
+		new = "/dev/null";
+
 	if (git_parse_advance_expected_str(&ctx->parse_ctx, "Binary files ") < 0 ||
 	    git_parse_advance_expected_str(&ctx->parse_ctx, old) < 0 ||
 	    git_parse_advance_expected_str(&ctx->parse_ctx, " and ") < 0 ||
diff --git a/tests/patch/patch_common.h b/tests/patch/patch_common.h
index 92ab769..1c6ad7e 100644
--- a/tests/patch/patch_common.h
+++ b/tests/patch/patch_common.h
@@ -878,6 +878,12 @@
 	"index 27184d9..7c94f9e 100644\n" \
 	"Binary files a/binary.bin and b/binary.bin differ\n"
 
+#define PATCH_ADD_BINARY_NOT_PRINTED \
+	"diff --git a/test.bin b/test.bin\n" \
+	"new file mode 100644\n" \
+	"index 0000000..9e0f96a\n" \
+	"Binary files /dev/null and b/test.bin differ\n"
+
 #define PATCH_ORIGINAL_NEW_FILE_WITH_SPACE \
 	"diff --git a/sp ace.txt b/sp ace.txt\n" \
 	"new file mode 100644\n" \
diff --git a/tests/patch/print.c b/tests/patch/print.c
index 4703c1d..c4ff479 100644
--- a/tests/patch/print.c
+++ b/tests/patch/print.c
@@ -172,3 +172,9 @@ void test_patch_print__binary_not_shown(void)
 	patch_print_from_patchfile(PATCH_BINARY_NOT_PRINTED,
 		strlen(PATCH_BINARY_NOT_PRINTED));
 }
+
+void test_patch_print__binary_add_not_shown(void)
+{
+	patch_print_from_patchfile(PATCH_ADD_BINARY_NOT_PRINTED,
+		strlen(PATCH_ADD_BINARY_NOT_PRINTED));
+}