attr.c: plug small leak in parse_attr_line()

If any error is noticed after the match_attr structure is allocated, we shouldn't just return NULL from this function. Add a fail_return label that frees the allocated structure and returns NULL, and consistently jump there when we want to return NULL after cleaning up. Signed-off-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Jan 27, 2017 at 18:01 UTC 62af896979403c6bcb441ca784121e720b161b30
1 file changed +8 -4
attr.c
+8 -4
@@ -223,7 +223,7 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
223 if (!macro_ok) {
224 fprintf(stderr, "%s not allowed: %s:%d\n",
225 name, src, lineno);
226 - return NULL;
226 + goto fail_return;
227 }
228 is_macro = 1;
229 name += strlen(ATTRIBUTE_MACRO_PREFIX);
@@ -233,7 +233,7 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
233 fprintf(stderr,
234 "%.*s is not a valid attribute name: %s:%d\n",
235 namelen, name, src, lineno);
236 - return NULL;
236 + goto fail_return;
237 }
238 }
239 else
@@ -246,7 +246,7 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
246 for (cp = states, num_attr = 0; *cp; num_attr++) {
247 cp = parse_attr(src, lineno, cp, NULL);
248 if (!cp)
249 - return NULL;
249 + goto fail_return;
250 }
251
252 res = xcalloc(1,
@@ -267,7 +267,7 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
267 if (res->u.pat.flags & EXC_FLAG_NEGATIVE) {
268 warning(_("Negative patterns are ignored in git attributes\n"
269 "Use '\\!' for literal leading exclamation."));
270 - return NULL;
270 + goto fail_return;
271 }
272 }
273 res->is_macro = is_macro;
@@ -283,6 +283,10 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
283 }
284
285 return res;
286 +
287 +fail_return:
288 + free(res);
289 + return NULL;
290 }
291
292 /*