[3.0] 424743b Fix varnishncsa memory leaks on duplicate headers
Martin Blix Grydeland
martin at varnish-cache.org
Mon Nov 5 13:44:20 CET 2012
commit 424743bb37f498b42d905a5e4ff30e160e0ceaa4
Author: Martin Blix Grydeland <martin at varnish-software.com>
Date: Wed Sep 12 15:26:20 2012 +0200
Fix varnishncsa memory leaks on duplicate headers
diff --git a/bin/varnishncsa/varnishncsa.c b/bin/varnishncsa/varnishncsa.c
index ff07ed5..f66bb18 100644
--- a/bin/varnishncsa/varnishncsa.c
+++ b/bin/varnishncsa/varnishncsa.c
@@ -136,13 +136,18 @@ isprefix(const char *str, const char *prefix, const char *end,
/*
* Returns a copy of the first consecutive sequence of non-space
- * characters in the string.
+ * characters in the string in dst. dst will be free'd first if non-NULL.
*/
-static char *
-trimfield(const char *str, const char *end)
+static void
+trimfield(char **dst, const char *str, const char *end)
{
size_t len;
- char *p;
+
+ /* free if already set */
+ if (*dst != NULL) {
+ free(*dst);
+ *dst = NULL;
+ }
/* skip leading space */
while (str < end && *str && *str == ' ')
@@ -154,22 +159,26 @@ trimfield(const char *str, const char *end)
break;
/* copy and return */
- p = malloc(len + 1);
- assert(p != NULL);
- memcpy(p, str, len);
- p[len] = '\0';
- return (p);
+ *dst = malloc(len + 1);
+ assert(*dst != NULL);
+ memcpy(*dst, str, len);
+ (*dst)[len] = '\0';
}
/*
* Returns a copy of the entire string with leading and trailing spaces
- * trimmed.
+ * trimmed in dst. dst will be free'd first if non-NULL.
*/
-static char *
-trimline(const char *str, const char *end)
+static void
+trimline(char **dst, const char *str, const char *end)
{
size_t len;
- char *p;
+
+ /* free if already set */
+ if (*dst != NULL) {
+ free(*dst);
+ *dst = NULL;
+ }
/* skip leading space */
while (str < end && *str && *str == ' ')
@@ -184,11 +193,10 @@ trimline(const char *str, const char *end)
--len;
/* copy and return */
- p = malloc(len + 1);
- assert(p != NULL);
- memcpy(p, str, len);
- p[len] = '\0';
- return (p);
+ *dst = malloc(len + 1);
+ assert(*dst != NULL);
+ memcpy(*dst, str, len);
+ (*dst)[len] = '\0';
}
static char *
@@ -284,9 +292,9 @@ collect_backend(struct logline *lp, enum VSL_tag_e tag, unsigned spec,
}
lp->active = 1;
if (isprefix(ptr, "default", end, &next))
- lp->df_h = trimfield(next, end);
+ trimfield(&lp->df_h, next, end);
else
- lp->df_h = trimfield(ptr, end);
+ trimfield(&lp->df_h, ptr, end);
break;
case SLT_TxRequest:
@@ -296,7 +304,7 @@ collect_backend(struct logline *lp, enum VSL_tag_e tag, unsigned spec,
clean_logline(lp);
break;
}
- lp->df_m = trimline(ptr, end);
+ trimline(&lp->df_m, ptr, end);
break;
case SLT_TxURL: {
@@ -310,10 +318,10 @@ collect_backend(struct logline *lp, enum VSL_tag_e tag, unsigned spec,
}
qs = index(ptr, '?');
if (qs) {
- lp->df_U = trimline(ptr, qs);
- lp->df_q = trimline(qs, end);
+ trimline(&lp->df_U, ptr, qs);
+ trimline(&lp->df_q, qs, end);
} else {
- lp->df_U = trimline(ptr, end);
+ trimline(&lp->df_U, ptr, end);
}
break;
}
@@ -325,7 +333,7 @@ collect_backend(struct logline *lp, enum VSL_tag_e tag, unsigned spec,
clean_logline(lp);
break;
}
- lp->df_H = trimline(ptr, end);
+ trimline(&lp->df_H, ptr, end);
break;
case SLT_RxStatus:
@@ -335,14 +343,14 @@ collect_backend(struct logline *lp, enum VSL_tag_e tag, unsigned spec,
clean_logline(lp);
break;
}
- lp->df_s = trimline(ptr, end);
+ trimline(&lp->df_s, ptr, end);
break;
case SLT_RxHeader:
if (!lp->active)
break;
if (isprefix(ptr, "content-length:", end, &next))
- lp->df_b = trimline(next, end);
+ trimline(&lp->df_b, next, end);
else if (isprefix(ptr, "date:", end, &next) &&
strptime(next, "%a, %d %b %Y %T", &lp->df_t) == NULL) {
clean_logline(lp);
@@ -357,16 +365,16 @@ collect_backend(struct logline *lp, enum VSL_tag_e tag, unsigned spec,
break;
if (isprefix(ptr, "authorization:", end, &next) &&
isprefix(next, "basic", end, &next)) {
- lp->df_u = trimline(next, end);
+ trimline(&lp->df_u, next, end);
} else {
struct hdr *h;
size_t l;
- h = malloc(sizeof(struct hdr));
+ h = calloc(1, sizeof(struct hdr));
AN(h);
AN(split);
l = strlen(split);
- h->key = trimline(ptr, split-1);
- h->value = trimline(split+1, split+l-1);
+ trimline(&h->key, ptr, split-1);
+ trimline(&h->value, split+1, split+l-1);
VTAILQ_INSERT_HEAD(&lp->req_headers, h, list);
}
break;
@@ -405,7 +413,7 @@ collect_client(struct logline *lp, enum VSL_tag_e tag, unsigned spec,
clean_logline(lp);
}
lp->active = 1;
- lp->df_h = trimfield(ptr, end);
+ trimfield(&lp->df_h, ptr, end);
break;
case SLT_RxRequest:
@@ -415,7 +423,7 @@ collect_client(struct logline *lp, enum VSL_tag_e tag, unsigned spec,
clean_logline(lp);
break;
}
- lp->df_m = trimline(ptr, end);
+ trimline(&lp->df_m, ptr, end);
break;
case SLT_RxURL: {
@@ -429,10 +437,10 @@ collect_client(struct logline *lp, enum VSL_tag_e tag, unsigned spec,
}
qs = index(ptr, '?');
if (qs) {
- lp->df_U = trimline(ptr, qs);
- lp->df_q = trimline(qs, end);
+ trimline(&lp->df_U, ptr, qs);
+ trimline(&lp->df_q, qs, end);
} else {
- lp->df_U = trimline(ptr, end);
+ trimline(&lp->df_U, ptr, end);
}
break;
}
@@ -444,7 +452,7 @@ collect_client(struct logline *lp, enum VSL_tag_e tag, unsigned spec,
clean_logline(lp);
break;
}
- lp->df_H = trimline(ptr, end);
+ trimline(&lp->df_H, ptr, end);
break;
case SLT_TxStatus:
@@ -453,7 +461,7 @@ collect_client(struct logline *lp, enum VSL_tag_e tag, unsigned spec,
if (lp->df_s != NULL)
clean_logline(lp);
else
- lp->df_s = trimline(ptr, end);
+ trimline(&lp->df_s, ptr, end);
break;
case SLT_TxHeader:
@@ -466,15 +474,14 @@ collect_client(struct logline *lp, enum VSL_tag_e tag, unsigned spec,
if (tag == SLT_RxHeader &&
isprefix(ptr, "authorization:", end, &next) &&
isprefix(next, "basic", end, &next)) {
- free(lp->df_u);
- lp->df_u = trimline(next, end);
+ trimline(&lp->df_u, next, end);
} else {
struct hdr *h;
- h = malloc(sizeof(struct hdr));
+ h = calloc(1, sizeof(struct hdr));
AN(h);
AN(split);
- h->key = trimline(ptr, split);
- h->value = trimline(split+1, end);
+ trimline(&h->key, ptr, split);
+ trimline(&h->value, split+1, end);
if (tag == SLT_RxHeader)
VTAILQ_INSERT_HEAD(&lp->req_headers, h, list);
else
@@ -491,12 +498,12 @@ collect_client(struct logline *lp, enum VSL_tag_e tag, unsigned spec,
break;
struct hdr *h;
- h = malloc(sizeof(struct hdr));
+ h = calloc(1, sizeof(struct hdr));
AN(h);
AN(split);
- h->key = trimline(ptr, split);
- h->value = trimline(split+1, end);
+ trimline(&h->key, ptr, split);
+ trimline(&h->value, split+1, end);
VTAILQ_INSERT_HEAD(&lp->vcl_log, h, list);
break;
@@ -528,7 +535,7 @@ collect_client(struct logline *lp, enum VSL_tag_e tag, unsigned spec,
clean_logline(lp);
break;
}
- lp->df_b = trimline(ptr, end);
+ trimline(&lp->df_b, ptr, end);
break;
case SLT_SessionClose:
@@ -550,6 +557,8 @@ collect_client(struct logline *lp, enum VSL_tag_e tag, unsigned spec,
clean_logline(lp);
break;
}
+ if (lp->df_ttfb != NULL)
+ free(lp->df_ttfb);
lp->df_ttfb = strdup(ttfb);
t = l;
localtime_r(&t, &lp->df_t);
More information about the varnish-commit
mailing list