summaryrefslogtreecommitdiff
path: root/src/patch_parse.c
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2019-10-21 18:56:59 +0200
committerPatrick Steinhardt <ps@pks.im>2019-10-21 20:07:42 +0200
commit37141ff7701e45ab0d97f311a4e0cc95cf527aa9 (patch)
tree1f9353c309550c7d3128570f007fdfa8e3de5d71 /src/patch_parse.c
parent468e3ddc344d6374a615fb2199005956ad0eb531 (diff)
downloadlibgit2-37141ff7701e45ab0d97f311a4e0cc95cf527aa9.tar.gz
patch_parse: detect overflow when calculating old/new line position
When the patch contains lines close to INT_MAX, then it may happen that we end up with an integer overflow when calculating the line of the current diff hunk. Reject such patches as unreasonable to avoid the integer overflow. As the calculation is performed on integers, we introduce two new helpers `git__add_int_overflow` and `git__sub_int_overflow` that perform the integer overflow check in a generic way.
Diffstat (limited to 'src/patch_parse.c')
-rw-r--r--src/patch_parse.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/src/patch_parse.c b/src/patch_parse.c
index 7a209fc80..5032e35c8 100644
--- a/src/patch_parse.c
+++ b/src/patch_parse.c
@@ -583,11 +583,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,