diff options
Diffstat (limited to 'src/patch_parse.c')
| -rw-r--r-- | src/patch_parse.c | 54 |
1 files changed, 39 insertions, 15 deletions
diff --git a/src/patch_parse.c b/src/patch_parse.c index 126918249..1bf0190c3 100644 --- a/src/patch_parse.c +++ b/src/patch_parse.c @@ -70,31 +70,36 @@ static int parse_header_path_buf(git_buf *path, git_patch_parse_ctx *ctx, size_t int error; if ((error = git_buf_put(path, ctx->parse_ctx.line, path_len)) < 0) - goto done; + return error; git_parse_advance_chars(&ctx->parse_ctx, path_len); git_buf_rtrim(path); - if (path->size > 0 && path->ptr[0] == '"') - error = git_buf_unquote(path); - - if (error < 0) - goto done; + if (path->size > 0 && path->ptr[0] == '"' && + (error = git_buf_unquote(path)) < 0) + return error; git_path_squash_slashes(path); -done: - return error; + if (!path->size) + return git_parse_err("patch contains empty path at line %"PRIuZ, + ctx->parse_ctx.line_num); + + return 0; } static int parse_header_path(char **out, git_patch_parse_ctx *ctx) { git_buf path = GIT_BUF_INIT; - int error = parse_header_path_buf(&path, ctx, header_path_len(ctx)); + int error; + if ((error = parse_header_path_buf(&path, ctx, header_path_len(ctx))) < 0) + goto out; *out = git_buf_detach(&path); +out: + git_buf_dispose(&path); return error; } @@ -104,6 +109,12 @@ static int parse_header_git_oldpath( git_buf old_path = GIT_BUF_INIT; int error; + if (patch->old_path) { + error = git_parse_err("patch contains duplicate old path at line %"PRIuZ, + ctx->parse_ctx.line_num); + goto out; + } + if ((error = parse_header_path_buf(&old_path, ctx, ctx->parse_ctx.line_len - 1)) < 0) goto out; @@ -120,9 +131,14 @@ static int parse_header_git_newpath( git_buf new_path = GIT_BUF_INIT; int error; - if ((error = parse_header_path_buf(&new_path, ctx, ctx->parse_ctx.line_len - 1)) < 0) + if (patch->new_path) { + error = git_parse_err("patch contains duplicate new path at line %"PRIuZ, + ctx->parse_ctx.line_num); goto out; + } + if ((error = parse_header_path_buf(&new_path, ctx, ctx->parse_ctx.line_len - 1)) < 0) + goto out; patch->new_path = git_buf_detach(&new_path); out: @@ -564,11 +580,17 @@ static int parse_hunk_body( !git_parse_ctx_contains_s(&ctx->parse_ctx, "@@ -"); git_parse_advance_line(&ctx->parse_ctx)) { + int old_lineno, new_lineno, origin, prefix = 1; char c; - int origin; - int prefix = 1; - int old_lineno = hunk->hunk.old_start + (hunk->hunk.old_lines - oldlines); - int new_lineno = hunk->hunk.new_start + (hunk->hunk.new_lines - newlines); + + if (git__add_int_overflow(&old_lineno, hunk->hunk.old_start, hunk->hunk.old_lines) || + git__sub_int_overflow(&old_lineno, old_lineno, oldlines) || + git__add_int_overflow(&new_lineno, hunk->hunk.new_start, hunk->hunk.new_lines) || + git__sub_int_overflow(&new_lineno, new_lineno, newlines)) { + error = git_parse_err("unrepresentable line count at line %"PRIuZ, + ctx->parse_ctx.line_num); + goto done; + } if (ctx->parse_ctx.line_len == 0 || ctx->parse_ctx.line[ctx->parse_ctx.line_len - 1] != '\n') { error = git_parse_err("invalid patch instruction at line %"PRIuZ, @@ -628,6 +650,7 @@ static int parse_hunk_body( line->content_len = ctx->parse_ctx.line_len - prefix; line->content = git__strndup(ctx->parse_ctx.line + prefix, line->content_len); + GIT_ERROR_CHECK_ALLOC(line->content); line->content_offset = ctx->parse_ctx.content_len - ctx->parse_ctx.remain_len; line->origin = origin; line->num_lines = 1; @@ -667,8 +690,9 @@ static int parse_hunk_body( memset(line, 0x0, sizeof(git_diff_line)); - line->content = git__strdup(ctx->parse_ctx.line); line->content_len = ctx->parse_ctx.line_len; + line->content = git__strndup(ctx->parse_ctx.line, line->content_len); + GIT_ERROR_CHECK_ALLOC(line->content); line->content_offset = ctx->parse_ctx.content_len - ctx->parse_ctx.remain_len; line->origin = eof_for_origin(last_origin); line->num_lines = 1; |
