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`.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
diff --git a/src/blame.h b/src/blame.h
index 7e23de8..d8db8d5 100644
--- a/src/blame.h
+++ b/src/blame.h
@@ -31,10 +31,10 @@ typedef struct git_blame__entry {
/* the first line of this group in the final image;
* internally all line numbers are 0 based.
*/
- int lno;
+ size_t lno;
/* how many lines this group has */
- int num_lines;
+ size_t num_lines;
/* the commit that introduced this group into the final image */
git_blame__origin *suspect;
@@ -51,7 +51,7 @@ typedef struct git_blame__entry {
/* the line number of the first line of this group in the
* 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
* scanning the lines over and over.
diff --git a/src/blame_git.c b/src/blame_git.c
index 67bae23..b8b5682 100644
--- a/src/blame_git.c
+++ b/src/blame_git.c
@@ -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 */
-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;
- int last_in_target = -1;
+ size_t last_in_target = 0;
+ bool found = false;
+
+ *out = 0;
for (e=blame->ent; e; e=e->next) {
if (e->guilty || !same_suspect(e->suspect, target))
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;
+ }
}
- 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)
* to be blamed for the parent, and after that portion.
*/
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) {
/* there is a pre-chunk part not blamed on the parent */
@@ -265,9 +272,9 @@ static void decref_split(git_blame__entry *split)
static void blame_overlap(
git_blame *blame,
git_blame__entry *e,
- int tlno,
- int plno,
- int same,
+ size_t tlno,
+ size_t plno,
+ size_t same,
git_blame__origin *parent)
{
git_blame__entry split[3] = {{0}};
@@ -285,9 +292,9 @@ static void blame_overlap(
*/
static void blame_chunk(
git_blame *blame,
- int tlno,
- int plno,
- int same,
+ size_t tlno,
+ size_t plno,
+ size_t same,
git_blame__origin *target,
git_blame__origin *parent)
{
@@ -314,7 +321,7 @@ static int my_emit(
blame_chunk(d->blame, d->tlno, d->plno, start_b, d->target, d->parent);
d->plno = start_a + count_a;
d->tlno = start_b + count_b;
-
+
return 0;
}
@@ -376,12 +383,11 @@ static int pass_blame_to_parent(
git_blame__origin *target,
git_blame__origin *parent)
{
- int last_in_target;
+ size_t last_in_target;
mmfile_t file_p, file_o;
blame_chunk_cb_data d = { blame, target, parent, 0, 0 };
- last_in_target = find_last_in_target(blame, target);
- if (last_in_target < 0)
+ if (!find_last_in_target(&last_in_target, blame, target))
return 1; /* nothing remains for this target */
fill_origin_blob(parent, &file_p);