[master] 20adece Move the responsibility for NUL terminating the RX buffer into the completion function.

Poul-Henning Kamp phk at FreeBSD.org
Mon Apr 3 10:30:09 CEST 2017


commit 20adece32a54597c21ac5874dcf9a7dd76f242bc
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Apr 3 08:28:56 2017 +0000

    Move the responsibility for NUL terminating the RX buffer into the
    completion function.
    
    Fixes #2285

diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c
index e36c9e3..02e1059 100644
--- a/bin/varnishd/cache/cache_session.c
+++ b/bin/varnishd/cache/cache_session.c
@@ -237,7 +237,7 @@ HTC_RxStuff(struct http_conn *htc, htc_complete_f *func,
 	double tmo;
 	double now;
 	enum htc_status_e hs;
-	int i;
+	ssize_t z;
 
 	CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
 	AN(htc->rfd);
@@ -255,15 +255,16 @@ HTC_RxStuff(struct http_conn *htc, htc_complete_f *func,
 		WS_ReleaseP(htc->ws, htc->rxbuf_b);
 		return (HTC_S_OVERFLOW);
 	}
-	if ((htc->ws->r - htc->rxbuf_b) - 1L < maxbytes)
-		maxbytes = (htc->ws->r - htc->rxbuf_b) - 1L; /* Space for NUL */
+	z = (htc->ws->r - htc->rxbuf_b);
+	if (z < maxbytes)
+		maxbytes = z;
 
 	while (1) {
 		now = VTIM_real();
 		AZ(htc->pipeline_b);
 		AZ(htc->pipeline_e);
-		assert(htc->rxbuf_e < htc->ws->r);
-		*htc->rxbuf_e = '\0';
+		assert(htc->rxbuf_e <= htc->ws->r);
+
 		hs = func(htc);
 		if (hs == HTC_S_OVERFLOW || hs == HTC_S_JUNK) {
 			WS_ReleaseP(htc->ws, htc->rxbuf_b);
@@ -290,21 +291,21 @@ HTC_RxStuff(struct http_conn *htc, htc_complete_f *func,
 		tmo = tn - now;
 		if (!isnan(ti) && ti < tn)
 			tmo = ti - now;
-		i = maxbytes - (htc->rxbuf_e - htc->rxbuf_b);
-		assert(i >= 0);
-		if (i == 0) {
+		z = maxbytes - (htc->rxbuf_e - htc->rxbuf_b);
+		assert(z >= 0);
+		if (z == 0) {
 			WS_ReleaseP(htc->ws, htc->rxbuf_b);
 			return (HTC_S_OVERFLOW);
 		}
 		if (tmo <= 0.0)
 			tmo = 1e-3;
-		i = VTCP_read(*htc->rfd, htc->rxbuf_e, i, tmo);
-		if (i == 0 || i == -1) {
+		z = VTCP_read(*htc->rfd, htc->rxbuf_e, z, tmo);
+		if (z == 0 || z == -1) {
 			WS_ReleaseP(htc->ws, htc->rxbuf_b);
 			return (HTC_S_EOF);
-		} else if (i > 0)
-			htc->rxbuf_e += i;
-		else if (i == -2) {
+		} else if (z > 0)
+			htc->rxbuf_e += z;
+		else if (z == -2) {
 			if (hs == HTC_S_EMPTY && ti <= now) {
 				WS_ReleaseP(htc->ws, htc->rxbuf_b);
 				return (HTC_S_IDLE);
diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c
index 05d23b3..2e691fd 100644
--- a/bin/varnishd/http1/cache_http1_proto.c
+++ b/bin/varnishd/http1/cache_http1_proto.c
@@ -73,7 +73,11 @@ HTTP1_Complete(struct http_conn *htc)
 	CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
 
 	assert(htc->rxbuf_e >= htc->rxbuf_b);
-	assert(*htc->rxbuf_e == '\0');
+	assert(htc->rxbuf_e <= htc->ws->r);
+
+	if (htc->rxbuf_e == htc->ws->r)
+		return (HTC_S_OVERFLOW);		// No space for NUL
+	*htc->rxbuf_e = '\0';
 
 	/* Skip any leading white space */
 	for (p = htc->rxbuf_b ; vct_islws(*p); p++)
diff --git a/bin/varnishd/proxy/cache_proxy_proto.c b/bin/varnishd/proxy/cache_proxy_proto.c
index 14e186a..d4231bc 100644
--- a/bin/varnishd/proxy/cache_proxy_proto.c
+++ b/bin/varnishd/proxy/cache_proxy_proto.c
@@ -297,6 +297,9 @@ vpx_complete(struct http_conn *htc)
 
 	CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
 
+	assert(htc->rxbuf_e >= htc->rxbuf_b);
+	assert(htc->rxbuf_e <= htc->ws->r);
+
 	l = htc->rxbuf_e - htc->rxbuf_b;
 	p = htc->rxbuf_b;
 	j = 0x3;
@@ -308,6 +311,8 @@ vpx_complete(struct http_conn *htc)
 		if (j == 0)
 			return (HTC_S_JUNK);
 		if (j == 1 && i == sizeof vpx1_sig) {
+			assert (htc->rxbuf_e < htc->ws->r);
+			*htc->rxbuf_e = '\0';
 			q = strchr(p + i, '\n');
 			if (q != NULL && (q - htc->rxbuf_b) > 107)
 				return (HTC_S_OVERFLOW);



More information about the varnish-commit mailing list