diff options
| author | Edward Thomson <ethomson@edwardthomson.com> | 2019-07-20 11:24:37 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-07-20 11:24:37 +0100 |
| commit | fd7a384b6849a407677c592f269603f4075d662a (patch) | |
| tree | 9943a282f1d882946d824c263f58346c3a9b5b71 /src/patch_parse.c | |
| parent | f33ca472d1a160ab5abbdf07d434455d7d1ee15c (diff) | |
| parent | b08932824e1ca202f1fcb81e94d329b77715a17c (diff) | |
| download | libgit2-fd7a384b6849a407677c592f269603f4075d662a.tar.gz | |
Merge pull request #5159 from pks-t/pks/patch-parse-old-missing-nl
patch_parse: handle missing newline indicator in old file
Diffstat (limited to 'src/patch_parse.c')
| -rw-r--r-- | src/patch_parse.c | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/src/patch_parse.c b/src/patch_parse.c index 5e5e5d941..70c33ed7d 100644 --- a/src/patch_parse.c +++ b/src/patch_parse.c @@ -524,6 +524,14 @@ fail: return -1; } +static int eof_for_origin(int origin) { + if (origin == GIT_DIFF_LINE_ADDITION) + return GIT_DIFF_LINE_ADD_EOFNL; + if (origin == GIT_DIFF_LINE_DELETION) + return GIT_DIFF_LINE_DEL_EOFNL; + return GIT_DIFF_LINE_CONTEXT_EOFNL; +} + static int parse_hunk_body( git_patch_parsed *patch, git_patch_hunk *hunk, @@ -534,6 +542,7 @@ static int parse_hunk_body( int oldlines = hunk->hunk.old_lines; int newlines = hunk->hunk.new_lines; + int last_origin = 0; for (; ctx->parse_ctx.remain_len > 1 && @@ -578,6 +587,21 @@ static int parse_hunk_body( old_lineno = -1; break; + case '\\': + /* + * If there are no oldlines left, then this is probably + * the "\ No newline at end of file" marker. Do not + * verify its format, as it may be localized. + */ + if (!oldlines) { + prefix = 0; + origin = eof_for_origin(last_origin); + old_lineno = -1; + new_lineno = -1; + break; + } + /* fall through */ + default: error = git_parse_err("invalid patch hunk at line %"PRIuZ, ctx->parse_ctx.line_num); goto done; @@ -597,6 +621,8 @@ static int parse_hunk_body( line->new_lineno = new_lineno; hunk->line_count++; + + last_origin = origin; } if (oldlines || newlines) { @@ -606,7 +632,8 @@ static int parse_hunk_body( goto done; } - /* Handle "\ No newline at end of file". Only expect the leading + /* + * Handle "\ No newline at end of file". Only expect the leading * backslash, though, because the rest of the string could be * localized. Because `diff` optimizes for the case where you * want to apply the patch by hand. @@ -617,11 +644,24 @@ static int parse_hunk_body( line = git_array_get(patch->base.lines, git_array_size(patch->base.lines) - 1); if (line->content_len < 1) { - error = git_parse_err("cannot trim trailing newline of empty line"); + error = git_parse_err("last line has no trailing newline"); goto done; } - line->content_len--; + line = git_array_alloc(patch->base.lines); + GIT_ERROR_CHECK_ALLOC(line); + + memset(line, 0x0, sizeof(git_diff_line)); + + line->content = ctx->parse_ctx.line; + line->content_len = ctx->parse_ctx.line_len; + line->content_offset = ctx->parse_ctx.content_len - ctx->parse_ctx.remain_len; + line->origin = eof_for_origin(last_origin); + line->num_lines = 1; + line->old_lineno = -1; + line->new_lineno = -1; + + hunk->line_count++; git_parse_advance_line(&ctx->parse_ctx); } |
