Prevent git blame from segfaulting on a missing author name
The human-readable author and committer name can be missing from commits imported from foreign SCM interfaces. Make sure we parse the "author" and "committer" line a bit more leniently and avoid segfaulting by assuming the name always exists. Signed-off-by: David Reiss <dreiss@facebook.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
David Reiss committed
Dec 22, 2009 at 10:51 UTC
c8cba79181abc139d7cba364bf868875426fc2c1
2 files changed
+23
-3
builtin-blame.c
+10
-3
@@ -1305,6 +1305,7 @@ static void get_ac_line(const char *inbuf, const char *what,
1305
error_out:
1306
/* Ugh */
1307
*tz = "(unknown)";
1308
+ strcpy(person, *tz);
1309
strcpy(mail, *tz);
1310
*time = 0;
1311
return;
@@ -1314,20 +1315,26 @@ static void get_ac_line(const char *inbuf, const char *what,
1315
tmp = person;
1316
tmp += len;
1317
*tmp = 0;
1317
- while (*tmp != ' ')
1318
+ while (person < tmp && *tmp != ' ')
1319
tmp--;
1320
+ if (tmp <= person)
1321
+ goto error_out;
1322
*tz = tmp+1;
1323
tzlen = (person+len)-(tmp+1);
1324
1325
*tmp = 0;
1323
- while (*tmp != ' ')
1326
+ while (person < tmp && *tmp != ' ')
1327
tmp--;
1328
+ if (tmp <= person)
1329
+ goto error_out;
1330
*time = strtoul(tmp, NULL, 10);
1331
timepos = tmp;
1332
1333
*tmp = 0;
1329
- while (*tmp != ' ')
1334
+ while (person < tmp && *tmp != ' ')
1335
tmp--;
1336
+ if (tmp <= person)
1337
+ return;
1338
mailpos = tmp + 1;
1339
*tmp = 0;
1340
maillen = timepos - tmp;
t/t8003-blame.sh
+13
@@ -144,4 +144,17 @@ test_expect_success 'blame path that used to be a directory' '
144
git blame HEAD^.. -- path
145
'
146
147
+test_expect_success 'blame to a commit with no author name' '
148
+ TREE=`git rev-parse HEAD:`
149
+ cat >badcommit <<EOF
150
+tree $TREE
151
+author <noname> 1234567890 +0000
152
+committer David Reiss <dreiss@facebook.com> 1234567890 +0000
153
+
154
+some message
155
+EOF
156
+ COMMIT=`git hash-object -t commit -w badcommit`
157
+ git --no-pager blame $COMMIT -- uno >/dev/null
158
+'
159
+
160
test_done