Commit 944dbd12 by Patrick Steinhardt

blame: use size_t for line counts in git_blame__entry

The `git_blame__entry` struct keeps track of line counts with
`int` fields. Since `int` is only guaranteed to be at least 16
bits we may overflow on certain platforms when line counts exceed
2^15.

Fix this by instead storing line counts in `size_t`.
parent cb1cb24c
...@@ -31,10 +31,10 @@ typedef struct git_blame__entry { ...@@ -31,10 +31,10 @@ typedef struct git_blame__entry {
/* the first line of this group in the final image; /* the first line of this group in the final image;
* internally all line numbers are 0 based. * internally all line numbers are 0 based.
*/ */
int lno; size_t lno;
/* how many lines this group has */ /* how many lines this group has */
int num_lines; size_t num_lines;
/* the commit that introduced this group into the final image */ /* the commit that introduced this group into the final image */
git_blame__origin *suspect; git_blame__origin *suspect;
...@@ -51,7 +51,7 @@ typedef struct git_blame__entry { ...@@ -51,7 +51,7 @@ typedef struct git_blame__entry {
/* the line number of the first line of this group in the /* the line number of the first line of this group in the
* suspect's file; internally all line numbers are 0 based. * suspect's file; internally all line numbers are 0 based.
*/ */
int s_lno; size_t s_lno;
/* how significant this entry is -- cached to avoid /* how significant this entry is -- cached to avoid
* scanning the lines over and over. * scanning the lines over and over.
......
...@@ -93,18 +93,25 @@ static bool same_suspect(git_blame__origin *a, git_blame__origin *b) ...@@ -93,18 +93,25 @@ static bool same_suspect(git_blame__origin *a, git_blame__origin *b)
} }
/* find the line number of the last line the target is suspected for */ /* find the line number of the last line the target is suspected for */
static int find_last_in_target(git_blame *blame, git_blame__origin *target) static bool find_last_in_target(size_t *out, git_blame *blame, git_blame__origin *target)
{ {
git_blame__entry *e; git_blame__entry *e;
int last_in_target = -1; size_t last_in_target = 0;
bool found = false;
*out = 0;
for (e=blame->ent; e; e=e->next) { for (e=blame->ent; e; e=e->next) {
if (e->guilty || !same_suspect(e->suspect, target)) if (e->guilty || !same_suspect(e->suspect, target))
continue; continue;
if (last_in_target < e->s_lno + e->num_lines) if (last_in_target < e->s_lno + e->num_lines) {
found = true;
last_in_target = e->s_lno + e->num_lines; last_in_target = e->s_lno + e->num_lines;
} }
return last_in_target; }
*out = last_in_target;
return found;
} }
/* /*
...@@ -122,9 +129,9 @@ static int find_last_in_target(git_blame *blame, git_blame__origin *target) ...@@ -122,9 +129,9 @@ static int find_last_in_target(git_blame *blame, git_blame__origin *target)
* to be blamed for the parent, and after that portion. * to be blamed for the parent, and after that portion.
*/ */
static void split_overlap(git_blame__entry *split, git_blame__entry *e, static void split_overlap(git_blame__entry *split, git_blame__entry *e,
int tlno, int plno, int same, git_blame__origin *parent) size_t tlno, size_t plno, size_t same, git_blame__origin *parent)
{ {
int chunk_end_lno; size_t chunk_end_lno;
if (e->s_lno < tlno) { if (e->s_lno < tlno) {
/* there is a pre-chunk part not blamed on the parent */ /* there is a pre-chunk part not blamed on the parent */
...@@ -265,9 +272,9 @@ static void decref_split(git_blame__entry *split) ...@@ -265,9 +272,9 @@ static void decref_split(git_blame__entry *split)
static void blame_overlap( static void blame_overlap(
git_blame *blame, git_blame *blame,
git_blame__entry *e, git_blame__entry *e,
int tlno, size_t tlno,
int plno, size_t plno,
int same, size_t same,
git_blame__origin *parent) git_blame__origin *parent)
{ {
git_blame__entry split[3] = {{0}}; git_blame__entry split[3] = {{0}};
...@@ -285,9 +292,9 @@ static void blame_overlap( ...@@ -285,9 +292,9 @@ static void blame_overlap(
*/ */
static void blame_chunk( static void blame_chunk(
git_blame *blame, git_blame *blame,
int tlno, size_t tlno,
int plno, size_t plno,
int same, size_t same,
git_blame__origin *target, git_blame__origin *target,
git_blame__origin *parent) git_blame__origin *parent)
{ {
...@@ -376,12 +383,11 @@ static int pass_blame_to_parent( ...@@ -376,12 +383,11 @@ static int pass_blame_to_parent(
git_blame__origin *target, git_blame__origin *target,
git_blame__origin *parent) git_blame__origin *parent)
{ {
int last_in_target; size_t last_in_target;
mmfile_t file_p, file_o; mmfile_t file_p, file_o;
blame_chunk_cb_data d = { blame, target, parent, 0, 0 }; blame_chunk_cb_data d = { blame, target, parent, 0, 0 };
last_in_target = find_last_in_target(blame, target); if (!find_last_in_target(&last_in_target, blame, target))
if (last_in_target < 0)
return 1; /* nothing remains for this target */ return 1; /* nothing remains for this target */
fill_origin_blob(parent, &file_p); fill_origin_blob(parent, &file_p);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment