| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -490,6 +490,14 @@ typedef struct { | |||
| 490 | 490 | ||
| 491 | 491 | /** Structure describing the binary contents of a diff. */ | |
| 492 | 492 | typedef struct { | |
| 493 | + /** | ||
| 494 | + * Whether there is data in this binary structure or not. If this | ||
| 495 | + * is `1`, then this was produced and included binary content. If | ||
| 496 | + * this is `0` then this was generated knowing only that a binary | ||
| 497 | + * file changed but without providing the data, probably from a patch | ||
| 498 | + * that said `Binary files a/file.txt and b/file.txt differ`. | ||
| 499 | + */ | ||
| 500 | + unsigned int contains_data; | ||
| 493 | 501 | git_diff_binary_file old_file; /**< The contents of the old file. */ | |
| 494 | 502 | git_diff_binary_file new_file; /**< The contents of the new file. */ | |
| 495 | 503 | } git_diff_binary; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -291,7 +291,15 @@ static int apply_binary( | |||
| 291 | 291 | git_patch *patch) | |
| 292 | 292 | { | |
| 293 | 293 | git_buf reverse = GIT_BUF_INIT; | |
| 294 | - int error; | ||
| 294 | + int error = 0; | ||
| 295 | + | ||
| 296 | + if (!patch->binary.contains_data) { | ||
| 297 | + error = apply_err("patch does not contain binary data"); | ||
| 298 | + goto done; | ||
| 299 | + } | ||
| 300 | + | ||
| 301 | + if (!patch->binary.old_file.datalen && !patch->binary.new_file.datalen) | ||
| 302 | + goto done; | ||
| 295 | 303 | ||
| 296 | 304 | /* first, apply the new_file delta to the given source */ | |
| 297 | 305 | if ((error = apply_binary_delta(out, source, source_len, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -500,7 +500,6 @@ static int diff_print_patch_file_binary_noshow( | |||
| 500 | 500 | &new_path, new_pfx, delta->new_file.path)) < 0) | |
| 501 | 501 | goto done; | |
| 502 | 502 | ||
| 503 | - | ||
| 504 | 503 | pi->line.num_lines = 1; | |
| 505 | 504 | error = diff_delta_format_with_paths( | |
| 506 | 505 | pi->buf, delta, "Binary files %s and %s differ\n", | |
@@ -521,13 +520,13 @@ static int diff_print_patch_file_binary( | |||
| 521 | 520 | size_t pre_binary_size; | |
| 522 | 521 | int error; | |
| 523 | 522 | ||
| 524 | - if ((pi->flags & GIT_DIFF_SHOW_BINARY) == 0) | ||
| 523 | + if (delta->status == GIT_DELTA_UNMODIFIED) | ||
| 524 | + return 0; | ||
| 525 | + | ||
| 526 | + if ((pi->flags & GIT_DIFF_SHOW_BINARY) == 0 || !binary->contains_data) | ||
| 525 | 527 | return diff_print_patch_file_binary_noshow( | |
| 526 | 528 | pi, delta, old_pfx, new_pfx); | |
| 527 | 529 | ||
| 528 | - if (binary->new_file.datalen == 0 && binary->old_file.datalen == 0) | ||
| 529 | - return 0; | ||
| 530 | - | ||
| 531 | 530 | pre_binary_size = pi->buf->size; | |
| 532 | 531 | git_buf_printf(pi->buf, "GIT binary patch\n"); | |
| 533 | 532 | pi->line.num_lines++; | |
@@ -563,8 +562,11 @@ static int diff_print_patch_file( | |||
| 563 | 562 | bool binary = (delta->flags & GIT_DIFF_FLAG_BINARY) || | |
| 564 | 563 | (pi->flags & GIT_DIFF_FORCE_BINARY); | |
| 565 | 564 | bool show_binary = !!(pi->flags & GIT_DIFF_SHOW_BINARY); | |
| 566 | - int id_strlen = binary && show_binary ? | ||
| 567 | - GIT_OID_HEXSZ : pi->id_strlen; | ||
| 565 | + int id_strlen = pi->id_strlen; | ||
| 566 | + | ||
| 567 | + if (binary && show_binary) | ||
| 568 | + id_strlen = delta->old_file.id_abbrev ? delta->old_file.id_abbrev : | ||
| 569 | + delta->new_file.id_abbrev; | ||
| 568 | 570 | ||
| 569 | 571 | GIT_UNUSED(progress); | |
| 570 | 572 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -17,6 +17,9 @@ int git_patch__invoke_callbacks( | |||
| 17 | 17 | if (file_cb) | |
| 18 | 18 | error = file_cb(patch->delta, 0, payload); | |
| 19 | 19 | ||
| 20 | + if (error) | ||
| 21 | + return error; | ||
| 22 | + | ||
| 20 | 23 | if ((patch->delta->flags & GIT_DIFF_FLAG_BINARY) != 0) { | |
| 21 | 24 | if (binary_cb) | |
| 22 | 25 | error = binary_cb(patch->delta, &patch->binary, payload); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -342,7 +342,7 @@ static int create_binary( | |||
| 342 | 342 | ||
| 343 | 343 | static int diff_binary(git_patch_generated_output *output, git_patch_generated *patch) | |
| 344 | 344 | { | |
| 345 | - git_diff_binary binary = {{0}}; | ||
| 345 | + git_diff_binary binary = {0}; | ||
| 346 | 346 | const char *old_data = patch->ofile.map.data; | |
| 347 | 347 | const char *new_data = patch->nfile.map.data; | |
| 348 | 348 | size_t old_len = patch->ofile.map.len, | |
@@ -352,6 +352,8 @@ static int diff_binary(git_patch_generated_output *output, git_patch_generated * | |||
| 352 | 352 | /* Only load contents if the user actually wants to diff | |
| 353 | 353 | * binary files. */ | |
| 354 | 354 | if (patch->base.diff_opts.flags & GIT_DIFF_SHOW_BINARY) { | |
| 355 | + binary.contains_data = 1; | ||
| 356 | + | ||
| 355 | 357 | /* Create the old->new delta (as the "new" side of the patch), | |
| 356 | 358 | * and the new->old delta (as the "old" side) | |
| 357 | 359 | */ | |
@@ -492,8 +494,17 @@ static int diff_single_generate(patch_generated_with_delta *pd, git_xdiff_output | |||
| 492 | 494 | patch_generated_init_common(patch); | |
| 493 | 495 | ||
| 494 | 496 | if (pd->delta.status == GIT_DELTA_UNMODIFIED && | |
| 495 | - !(patch->ofile.opts_flags & GIT_DIFF_INCLUDE_UNMODIFIED)) | ||
| 497 | + !(patch->ofile.opts_flags & GIT_DIFF_INCLUDE_UNMODIFIED)) { | ||
| 498 | + | ||
| 499 | + /* Even empty patches are flagged as binary, and even though | ||
| 500 | + * there's no difference, we flag this as "containing data" | ||
| 501 | + * (the data is known to be empty, as opposed to wholly unknown). | ||
| 502 | + */ | ||
| 503 | + if (patch->base.diff_opts.flags & GIT_DIFF_SHOW_BINARY) | ||
| 504 | + patch->base.binary.contains_data = 1; | ||
| 505 | + | ||
| 496 | 506 | return error; | |
| 507 | + } | ||
| 497 | 508 | ||
| 498 | 509 | error = patch_generated_invoke_file_callback(patch, (git_patch_generated_output *)xo); | |
| 499 | 510 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -74,8 +74,8 @@ static int parse_advance_expected( | |||
| 74 | 74 | return 0; | |
| 75 | 75 | } | |
| 76 | 76 | ||
| 77 | - #define parse_advance_expected_s(ctx, str) \ | ||
| 78 | - parse_advance_expected(ctx, str, sizeof(str) - 1) | ||
| 77 | + #define parse_advance_expected_str(ctx, str) \ | ||
| 78 | + parse_advance_expected(ctx, str, strlen(str)) | ||
| 79 | 79 | ||
| 80 | 80 | static int parse_advance_ws(git_patch_parse_ctx *ctx) | |
| 81 | 81 | { | |
@@ -220,7 +220,7 @@ static int parse_header_git_index( | |||
| 220 | 220 | { | |
| 221 | 221 | if (parse_header_oid(&patch->base.delta->old_file.id, | |
| 222 | 222 | &patch->base.delta->old_file.id_abbrev, ctx) < 0 || | |
| 223 | - parse_advance_expected_s(ctx, "..") < 0 || | ||
| 223 | + parse_advance_expected_str(ctx, "..") < 0 || | ||
| 224 | 224 | parse_header_oid(&patch->base.delta->new_file.id, | |
| 225 | 225 | &patch->base.delta->new_file.id_abbrev, ctx) < 0) | |
| 226 | 226 | return -1; | |
@@ -336,7 +336,7 @@ static int parse_header_percent(uint16_t *out, git_patch_parse_ctx *ctx) | |||
| 336 | 336 | ||
| 337 | 337 | parse_advance_chars(ctx, (end - ctx->line)); | |
| 338 | 338 | ||
| 339 | - if (parse_advance_expected_s(ctx, "%") < 0) | ||
| 339 | + if (parse_advance_expected_str(ctx, "%") < 0) | ||
| 340 | 340 | return -1; | |
| 341 | 341 | ||
| 342 | 342 | if (val > 100) | |
@@ -379,6 +379,7 @@ static const header_git_op header_git_ops[] = { | |||
| 379 | 379 | { "diff --git ", NULL }, | |
| 380 | 380 | { "@@ -", NULL }, | |
| 381 | 381 | { "GIT binary patch", NULL }, | |
| 382 | + { "Binary files ", NULL }, | ||
| 382 | 383 | { "--- ", parse_header_git_oldpath }, | |
| 383 | 384 | { "+++ ", parse_header_git_newpath }, | |
| 384 | 385 | { "index ", parse_header_git_index }, | |
@@ -404,7 +405,7 @@ static int parse_header_git( | |||
| 404 | 405 | int error = 0; | |
| 405 | 406 | ||
| 406 | 407 | /* Parse the diff --git line */ | |
| 407 | - if (parse_advance_expected_s(ctx, "diff --git ") < 0) | ||
| 408 | + if (parse_advance_expected_str(ctx, "diff --git ") < 0) | ||
| 408 | 409 | return parse_err("corrupt git diff header at line %d", ctx->line_num); | |
| 409 | 410 | ||
| 410 | 411 | if (parse_header_path(&patch->header_old_path, ctx) < 0) | |
@@ -443,7 +444,7 @@ static int parse_header_git( | |||
| 443 | 444 | goto done; | |
| 444 | 445 | ||
| 445 | 446 | parse_advance_ws(ctx); | |
| 446 | - parse_advance_expected_s(ctx, "\n"); | ||
| 447 | + parse_advance_expected_str(ctx, "\n"); | ||
| 447 | 448 | ||
| 448 | 449 | if (ctx->line_len > 0) { | |
| 449 | 450 | error = parse_err("trailing data at line %d", ctx->line_num); | |
@@ -505,27 +506,27 @@ static int parse_hunk_header( | |||
| 505 | 506 | hunk->hunk.old_lines = 1; | |
| 506 | 507 | hunk->hunk.new_lines = 1; | |
| 507 | 508 | ||
| 508 | - if (parse_advance_expected_s(ctx, "@@ -") < 0 || | ||
| 509 | + if (parse_advance_expected_str(ctx, "@@ -") < 0 || | ||
| 509 | 510 | parse_int(&hunk->hunk.old_start, ctx) < 0) | |
| 510 | 511 | goto fail; | |
| 511 | 512 | ||
| 512 | 513 | if (ctx->line_len > 0 && ctx->line[0] == ',') { | |
| 513 | - if (parse_advance_expected_s(ctx, ",") < 0 || | ||
| 514 | + if (parse_advance_expected_str(ctx, ",") < 0 || | ||
| 514 | 515 | parse_int(&hunk->hunk.old_lines, ctx) < 0) | |
| 515 | 516 | goto fail; | |
| 516 | 517 | } | |
| 517 | 518 | ||
| 518 | - if (parse_advance_expected_s(ctx, " +") < 0 || | ||
| 519 | + if (parse_advance_expected_str(ctx, " +") < 0 || | ||
| 519 | 520 | parse_int(&hunk->hunk.new_start, ctx) < 0) | |
| 520 | 521 | goto fail; | |
| 521 | 522 | ||
| 522 | 523 | if (ctx->line_len > 0 && ctx->line[0] == ',') { | |
| 523 | - if (parse_advance_expected_s(ctx, ",") < 0 || | ||
| 524 | + if (parse_advance_expected_str(ctx, ",") < 0 || | ||
| 524 | 525 | parse_int(&hunk->hunk.new_lines, ctx) < 0) | |
| 525 | 526 | goto fail; | |
| 526 | 527 | } | |
| 527 | 528 | ||
| 528 | - if (parse_advance_expected_s(ctx, " @@") < 0) | ||
| 529 | + if (parse_advance_expected_str(ctx, " @@") < 0) | ||
| 529 | 530 | goto fail; | |
| 530 | 531 | ||
| 531 | 532 | parse_advance_line(ctx); | |
@@ -782,7 +783,7 @@ static int parse_patch_binary( | |||
| 782 | 783 | { | |
| 783 | 784 | int error; | |
| 784 | 785 | ||
| 785 | - if (parse_advance_expected_s(ctx, "GIT binary patch") < 0 || | ||
| 786 | + if (parse_advance_expected_str(ctx, "GIT binary patch") < 0 || | ||
| 786 | 787 | parse_advance_nl(ctx) < 0) | |
| 787 | 788 | return parse_err("corrupt git binary header at line %d", ctx->line_num); | |
| 788 | 789 | ||
@@ -804,6 +805,24 @@ static int parse_patch_binary( | |||
| 804 | 805 | return parse_err("corrupt git binary patch separator at line %d", | |
| 805 | 806 | ctx->line_num); | |
| 806 | 807 | ||
| 808 | + patch->base.binary.contains_data = 1; | ||
| 809 | + patch->base.delta->flags |= GIT_DIFF_FLAG_BINARY; | ||
| 810 | + return 0; | ||
| 811 | + } | ||
| 812 | + | ||
| 813 | + static int parse_patch_binary_nodata( | ||
| 814 | + git_patch_parsed *patch, | ||
| 815 | + git_patch_parse_ctx *ctx) | ||
| 816 | + { | ||
| 817 | + if (parse_advance_expected_str(ctx, "Binary files ") < 0 || | ||
| 818 | + parse_advance_expected_str(ctx, patch->header_old_path) < 0 || | ||
| 819 | + parse_advance_expected_str(ctx, " and ") < 0 || | ||
| 820 | + parse_advance_expected_str(ctx, patch->header_new_path) < 0 || | ||
| 821 | + parse_advance_expected_str(ctx, " differ") < 0 || | ||
| 822 | + parse_advance_nl(ctx) < 0) | ||
| 823 | + return parse_err("corrupt git binary header at line %d", ctx->line_num); | ||
| 824 | + | ||
| 825 | + patch->base.binary.contains_data = 0; | ||
| 807 | 826 | patch->base.delta->flags |= GIT_DIFF_FLAG_BINARY; | |
| 808 | 827 | return 0; | |
| 809 | 828 | } | |
@@ -840,6 +859,8 @@ static int parse_patch_body( | |||
| 840 | 859 | { | |
| 841 | 860 | if (parse_ctx_contains_s(ctx, "GIT binary patch")) | |
| 842 | 861 | return parse_patch_binary(patch, ctx); | |
| 862 | + else if (parse_ctx_contains_s(ctx, "Binary files ")) | ||
| 863 | + return parse_patch_binary_nodata(patch, ctx); | ||
| 843 | 864 | else | |
| 844 | 865 | return parse_patch_hunks(patch, ctx); | |
| 845 | 866 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -661,3 +661,8 @@ | |||
| 661 | 661 | "\n" \ | |
| 662 | 662 | "delta 48\n" \ | |
| 663 | 663 | "mc$~Y)c#%<%fq{_;hPgsAGK(h)CJASj=y9P)1m{m|^9BI99|yz$\n\n" | |
| 664 | + | ||
| 665 | + #define PATCH_BINARY_NOT_PRINTED \ | ||
| 666 | + "diff --git a/binary.bin b/binary.bin\n" \ | ||
| 667 | + "index 27184d9..7c94f9e 100644\n" \ | ||
| 668 | + "Binary files a/binary.bin and b/binary.bin differ\n" | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -166,3 +166,9 @@ void test_patch_print__not_reversible(void) | |||
| 166 | 166 | patch_print_from_patchfile(PATCH_BINARY_NOT_REVERSIBLE, | |
| 167 | 167 | strlen(PATCH_BINARY_NOT_REVERSIBLE)); | |
| 168 | 168 | } | |
| 169 | + | ||
| 170 | + void test_patch_print__binary_not_shown(void) | ||
| 171 | + { | ||
| 172 | + patch_print_from_patchfile(PATCH_BINARY_NOT_PRINTED, | ||
| 173 | + strlen(PATCH_BINARY_NOT_PRINTED)); | ||
| 174 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments