Navigation Menu
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Read binary patches (with no binary data) #3923
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -74,8 +74,8 @@ static int parse_advance_expected( | |
| return 0; | ||
| } | ||
|
|
||
| #define parse_advance_expected_s(ctx, str) \ | ||
| parse_advance_expected(ctx, str, sizeof(str) - 1) | ||
| #define parse_advance_expected_str(ctx, str) \ | ||
| parse_advance_expected(ctx, str, strlen(str)) | ||
|
|
||
| static int parse_advance_ws(git_patch_parse_ctx *ctx) | ||
| { | ||
|
|
@@ -220,7 +220,7 @@ static int parse_header_git_index( | |
| { | ||
| if (parse_header_oid(&patch->base.delta->old_file.id, | ||
| &patch->base.delta->old_file.id_abbrev, ctx) < 0 || | ||
| parse_advance_expected_s(ctx, "..") < 0 || | ||
| parse_advance_expected_str(ctx, "..") < 0 || | ||
| parse_header_oid(&patch->base.delta->new_file.id, | ||
| &patch->base.delta->new_file.id_abbrev, ctx) < 0) | ||
| return -1; | ||
|
|
@@ -336,7 +336,7 @@ static int parse_header_percent(uint16_t *out, git_patch_parse_ctx *ctx) | |
|
|
||
| parse_advance_chars(ctx, (end - ctx->line)); | ||
|
|
||
| if (parse_advance_expected_s(ctx, "%") < 0) | ||
| if (parse_advance_expected_str(ctx, "%") < 0) | ||
| return -1; | ||
|
|
||
| if (val > 100) | ||
|
|
@@ -379,6 +379,7 @@ static const header_git_op header_git_ops[] = { | |
| { "diff --git ", NULL }, | ||
| { "@@ -", NULL }, | ||
| { "GIT binary patch", NULL }, | ||
| { "Binary files ", NULL }, | ||
| { "--- ", parse_header_git_oldpath }, | ||
| { "+++ ", parse_header_git_newpath }, | ||
| { "index ", parse_header_git_index }, | ||
|
|
@@ -404,7 +405,7 @@ static int parse_header_git( | |
| int error = 0; | ||
|
|
||
| /* Parse the diff --git line */ | ||
| if (parse_advance_expected_s(ctx, "diff --git ") < 0) | ||
| if (parse_advance_expected_str(ctx, "diff --git ") < 0) | ||
| return parse_err("corrupt git diff header at line %d", ctx->line_num); | ||
|
|
||
| if (parse_header_path(&patch->header_old_path, ctx) < 0) | ||
|
|
@@ -443,7 +444,7 @@ static int parse_header_git( | |
| goto done; | ||
|
|
||
| parse_advance_ws(ctx); | ||
| parse_advance_expected_s(ctx, "\n"); | ||
| parse_advance_expected_str(ctx, "\n"); | ||
|
|
||
| if (ctx->line_len > 0) { | ||
| error = parse_err("trailing data at line %d", ctx->line_num); | ||
|
|
@@ -505,27 +506,27 @@ static int parse_hunk_header( | |
| hunk->hunk.old_lines = 1; | ||
| hunk->hunk.new_lines = 1; | ||
|
|
||
| if (parse_advance_expected_s(ctx, "@@ -") < 0 || | ||
| if (parse_advance_expected_str(ctx, "@@ -") < 0 || | ||
| parse_int(&hunk->hunk.old_start, ctx) < 0) | ||
| goto fail; | ||
|
|
||
| if (ctx->line_len > 0 && ctx->line[0] == ',') { | ||
| if (parse_advance_expected_s(ctx, ",") < 0 || | ||
| if (parse_advance_expected_str(ctx, ",") < 0 || | ||
| parse_int(&hunk->hunk.old_lines, ctx) < 0) | ||
| goto fail; | ||
| } | ||
|
|
||
| if (parse_advance_expected_s(ctx, " +") < 0 || | ||
| if (parse_advance_expected_str(ctx, " +") < 0 || | ||
| parse_int(&hunk->hunk.new_start, ctx) < 0) | ||
| goto fail; | ||
|
|
||
| if (ctx->line_len > 0 && ctx->line[0] == ',') { | ||
| if (parse_advance_expected_s(ctx, ",") < 0 || | ||
| if (parse_advance_expected_str(ctx, ",") < 0 || | ||
| parse_int(&hunk->hunk.new_lines, ctx) < 0) | ||
| goto fail; | ||
| } | ||
|
|
||
| if (parse_advance_expected_s(ctx, " @@") < 0) | ||
| if (parse_advance_expected_str(ctx, " @@") < 0) | ||
| goto fail; | ||
|
|
||
| parse_advance_line(ctx); | ||
|
|
@@ -782,7 +783,7 @@ static int parse_patch_binary( | |
| { | ||
| int error; | ||
|
|
||
| if (parse_advance_expected_s(ctx, "GIT binary patch") < 0 || | ||
| if (parse_advance_expected_str(ctx, "GIT binary patch") < 0 || | ||
| parse_advance_nl(ctx) < 0) | ||
| return parse_err("corrupt git binary header at line %d", ctx->line_num); | ||
|
|
||
|
|
@@ -804,6 +805,24 @@ static int parse_patch_binary( | |
| return parse_err("corrupt git binary patch separator at line %d", | ||
| ctx->line_num); | ||
|
|
||
| patch->base.binary.contains_data = 1; | ||
| patch->base.delta->flags |= GIT_DIFF_FLAG_BINARY; | ||
| return 0; | ||
| } | ||
|
|
||
| static int parse_patch_binary_nodata( | ||
| git_patch_parsed *patch, | ||
| git_patch_parse_ctx *ctx) | ||
| { | ||
| if (parse_advance_expected_str(ctx, "Binary files ") < 0 || | ||
| parse_advance_expected_str(ctx, patch->header_old_path) < 0 || | ||
| parse_advance_expected_str(ctx, " and ") < 0 || | ||
| parse_advance_expected_str(ctx, patch->header_new_path) < 0 || | ||
| parse_advance_expected_str(ctx, " differ") < 0 || | ||
| parse_advance_nl(ctx) < 0) | ||
| return parse_err("corrupt git binary header at line %d", ctx->line_num); | ||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just wondering: can it happen that we get as input a
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Only when we're actually given binary data, eg |
||
| patch->base.binary.contains_data = 0; | ||
| patch->base.delta->flags |= GIT_DIFF_FLAG_BINARY; | ||
| return 0; | ||
| } | ||
|
|
@@ -840,6 +859,8 @@ static int parse_patch_body( | |
| { | ||
| if (parse_ctx_contains_s(ctx, "GIT binary patch")) | ||
| return parse_patch_binary(patch, ctx); | ||
| else if (parse_ctx_contains_s(ctx, "Binary files ")) | ||
| return parse_patch_binary_nodata(patch, ctx); | ||
| else | ||
| return parse_patch_hunks(patch, ctx); | ||
| } | ||
|
|
||

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this even be triggered? If
contains_data == 0, we'll usually haveold_file.datalen == 0 && new_file.datalen == 0due to the patch not being parsed. So actually, we'd already skip this check due to the previous check. I'd rather expect that this statement and the previous statement needs to be swapped.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, you're right. I did flip these checks, which covered up the fact that I wasn't successfully setting
contains_data = 1when we were creating a diff from unmodified binary files. Fixed this up.