ref-filter: free item->value and item->value->s

Release item->value. Initialize item->value->s dynamically and then release its resources. Release some local variables. Final goal of this patch is to reduce number of memory leaks. Signed-off-by: Olga Telezhnaia <olyatelezhnaya@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Olga Telezhnaya committed Oct 18, 2018 at 07:28 UTC f0062d3b74cfd4425188e16cbda358b1e0228d85
1 file changed +54 -42
ref-filter.c
+54 -42
@@ -875,7 +875,7 @@ static void grab_common_values(struct atom_value *val, int deref, struct expand_
875 if (deref)
876 name++;
877 if (!strcmp(name, "objecttype"))
878 - v->s = type_name(oi->type);
878 + v->s = xstrdup(type_name(oi->type));
879 else if (!strcmp(name, "objectsize")) {
880 v->value = oi->size;
881 v->s = xstrfmt("%lu", oi->size);
@@ -899,9 +899,9 @@ static void grab_tag_values(struct atom_value *val, int deref, struct object *ob
899 if (deref)
900 name++;
901 if (!strcmp(name, "tag"))
902 - v->s = tag->tag;
902 + v->s = xstrdup(tag->tag);
903 else if (!strcmp(name, "type") && tag->tagged)
904 - v->s = type_name(tag->tagged->type);
904 + v->s = xstrdup(type_name(tag->tagged->type));
905 else if (!strcmp(name, "object") && tag->tagged)
906 v->s = xstrdup(oid_to_hex(&tag->tagged->oid));
907 }
@@ -1032,7 +1032,7 @@ static void grab_date(const char *buf, struct atom_value *v, const char *atomnam
1032 v->value = timestamp;
1033 return;
1034 bad:
1035 - v->s = "";
1035 + v->s = xstrdup("");
1036 v->value = 0;
1037 }
1038
@@ -1227,7 +1227,7 @@ static void fill_missing_values(struct atom_value *val)
1227 for (i = 0; i < used_atom_cnt; i++) {
1228 struct atom_value *v = &val[i];
1229 if (v->s == NULL)
1230 - v->s = "";
1230 + v->s = xstrdup("");
1231 }
1232 }
1233
@@ -1273,7 +1273,8 @@ static inline char *copy_advance(char *dst, const char *src)
1273 static const char *lstrip_ref_components(const char *refname, int len)
1274 {
1275 long remaining = len;
1276 - const char *start = refname;
1276 + const char *start = xstrdup(refname);
1277 + const char *to_free = start;
1278
1279 if (len < 0) {
1280 int i;
@@ -1294,20 +1295,24 @@ static const char *lstrip_ref_components(const char *refname, int len)
1295 while (remaining > 0) {
1296 switch (*start++) {
1297 case '\0':
1297 - return "";
1298 + free((char *)to_free);
1299 + return xstrdup("");
1300 case '/':
1301 remaining--;
1302 break;
1303 }
1304 }
1305
1306 + start = xstrdup(start);
1307 + free((char *)to_free);
1308 return start;
1309 }
1310
1311 static const char *rstrip_ref_components(const char *refname, int len)
1312 {
1313 long remaining = len;
1310 - char *start = xstrdup(refname);
1314 + const char *start = xstrdup(refname);
1315 + const char *to_free = start;
1316
1317 if (len < 0) {
1318 int i;
@@ -1327,9 +1332,10 @@ static const char *rstrip_ref_components(const char *refname, int len)
1332
1333 while (remaining-- > 0) {
1334 char *p = strrchr(start, '/');
1330 - if (p == NULL)
1331 - return "";
1332 - else
1335 + if (p == NULL) {
1336 + free((char *)to_free);
1337 + return xstrdup("");
1338 + } else
1339 p[0] = '\0';
1340 }
1341 return start;
@@ -1344,7 +1350,7 @@ static const char *show_ref(struct refname_atom *atom, const char *refname)
1350 else if (atom->option == R_RSTRIP)
1351 return rstrip_ref_components(refname, atom->rstrip);
1352 else
1347 - return refname;
1353 + return xstrdup(refname);
1354 }
1355
1356 static void fill_remote_ref_details(struct used_atom *atom, const char *refname,
@@ -1358,7 +1364,7 @@ static void fill_remote_ref_details(struct used_atom *atom, const char *refname,
1364 NULL, AHEAD_BEHIND_FULL) < 0) {
1365 *s = xstrdup(msgs.gone);
1366 } else if (!num_ours && !num_theirs)
1361 - *s = "";
1367 + *s = xstrdup("");
1368 else if (!num_ours)
1369 *s = xstrfmt(msgs.behind, num_theirs);
1370 else if (!num_theirs)
@@ -1373,36 +1379,31 @@ static void fill_remote_ref_details(struct used_atom *atom, const char *refname,
1379 }
1380 } else if (atom->u.remote_ref.option == RR_TRACKSHORT) {
1381 if (stat_tracking_info(branch, &num_ours, &num_theirs,
1376 - NULL, AHEAD_BEHIND_FULL) < 0)
1382 + NULL, AHEAD_BEHIND_FULL) < 0) {
1383 + *s = xstrdup("");
1384 return;
1378 -
1385 + }
1386 if (!num_ours && !num_theirs)
1380 - *s = "=";
1387 + *s = xstrdup("=");
1388 else if (!num_ours)
1382 - *s = "<";
1389 + *s = xstrdup("<");
1390 else if (!num_theirs)
1384 - *s = ">";
1391 + *s = xstrdup(">");
1392 else
1386 - *s = "<>";
1393 + *s = xstrdup("<>");
1394 } else if (atom->u.remote_ref.option == RR_REMOTE_NAME) {
1395 int explicit;
1396 const char *remote = atom->u.remote_ref.push ?
1397 pushremote_for_branch(branch, &explicit) :
1398 remote_for_branch(branch, &explicit);
1392 - if (explicit)
1393 - *s = xstrdup(remote);
1394 - else
1395 - *s = "";
1399 + *s = xstrdup(explicit ? remote : "");
1400 } else if (atom->u.remote_ref.option == RR_REMOTE_REF) {
1401 int explicit;
1402 const char *merge;
1403
1404 merge = remote_ref_for_branch(branch, atom->u.remote_ref.push,
1405 &explicit);
1402 - if (explicit)
1403 - *s = xstrdup(merge);
1404 - else
1405 - *s = "";
1406 + *s = xstrdup(explicit ? merge : "");
1407 } else
1408 BUG("unhandled RR_* enum");
1409 }
@@ -1451,7 +1452,7 @@ char *get_head_description(void)
1452 static const char *get_symref(struct used_atom *atom, struct ref_array_item *ref)
1453 {
1454 if (!ref->symref)
1454 - return "";
1455 + return xstrdup("");
1456 else
1457 return show_ref(&atom->u.refname, ref->symref);
1458 }
@@ -1510,7 +1511,7 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
1511 ref->symref = resolve_refdup(ref->refname, RESOLVE_REF_READING,
1512 NULL, NULL);
1513 if (!ref->symref)
1513 - ref->symref = "";
1514 + ref->symref = xstrdup("");
1515 }
1516
1517 /* Fill in specials first */
@@ -1536,20 +1537,23 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
1537 refname = get_symref(atom, ref);
1538 else if (starts_with(name, "upstream")) {
1539 const char *branch_name;
1539 - v->s = "";
1540 /* only local branches may have an upstream */
1541 if (!skip_prefix(ref->refname, "refs/heads/",
1542 - &branch_name))
1542 + &branch_name)) {
1543 + v->s = xstrdup("");
1544 continue;
1545 + }
1546 branch = branch_get(branch_name);
1547
1548 refname = branch_get_upstream(branch, NULL);
1549 if (refname)
1550 fill_remote_ref_details(atom, refname, branch, &v->s);
1551 + else
1552 + v->s = xstrdup("");
1553 continue;
1554 } else if (atom->u.remote_ref.push) {
1555 const char *branch_name;
1552 - v->s = "";
1556 + v->s = xstrdup("");
1557 if (!skip_prefix(ref->refname, "refs/heads/",
1558 &branch_name))
1559 continue;
@@ -1562,10 +1566,12 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
1566 if (!refname)
1567 continue;
1568 }
1569 + /* We will definitely re-init v->s on the next line. */
1570 + free((char *)v->s);
1571 fill_remote_ref_details(atom, refname, branch, &v->s);
1572 continue;
1573 } else if (starts_with(name, "color:")) {
1568 - v->s = atom->u.color;
1574 + v->s = xstrdup(atom->u.color);
1575 continue;
1576 } else if (!strcmp(name, "flag")) {
1577 char buf[256], *cp = buf;
@@ -1574,7 +1580,7 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
1580 if (ref->flag & REF_ISPACKED)
1581 cp = copy_advance(cp, ",packed");
1582 if (cp == buf)
1577 - v->s = "";
1583 + v->s = xstrdup("");
1584 else {
1585 *cp = '\0';
1586 v->s = xstrdup(buf + 1);
@@ -1584,40 +1590,42 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
1590 continue;
1591 } else if (!strcmp(name, "HEAD")) {
1592 if (atom->u.head && !strcmp(ref->refname, atom->u.head))
1587 - v->s = "*";
1593 + v->s = xstrdup("*");
1594 else
1589 - v->s = " ";
1595 + v->s = xstrdup(" ");
1596 continue;
1597 } else if (starts_with(name, "align")) {
1598 v->handler = align_atom_handler;
1593 - v->s = "";
1599 + v->s = xstrdup("");
1600 continue;
1601 } else if (!strcmp(name, "end")) {
1602 v->handler = end_atom_handler;
1597 - v->s = "";
1603 + v->s = xstrdup("");
1604 continue;
1605 } else if (starts_with(name, "if")) {
1606 const char *s;
1601 - v->s = "";
1607 if (skip_prefix(name, "if:", &s))
1608 v->s = xstrdup(s);
1609 + else
1610 + v->s = xstrdup("");
1611 v->handler = if_atom_handler;
1612 continue;
1613 } else if (!strcmp(name, "then")) {
1614 v->handler = then_atom_handler;
1608 - v->s = "";
1615 + v->s = xstrdup("");
1616 continue;
1617 } else if (!strcmp(name, "else")) {
1618 v->handler = else_atom_handler;
1612 - v->s = "";
1619 + v->s = xstrdup("");
1620 continue;
1621 } else
1622 continue;
1623
1624 if (!deref)
1618 - v->s = refname;
1625 + v->s = xstrdup(refname);
1626 else
1627 v->s = xstrfmt("%s^{}", refname);
1628 + free((char *)refname);
1629 }
1630
1631 for (i = 0; i < used_atom_cnt; i++) {
@@ -1988,6 +1996,10 @@ static int ref_filter_handler(const char *refname, const struct object_id *oid,
1996 static void free_array_item(struct ref_array_item *item)
1997 {
1998 free((char *)item->symref);
1999 + if (item->value) {
2000 + free((char *)item->value->s);
2001 + free(item->value);
2002 + }
2003 free(item);
2004 }
2005