[master] 904659a14 Evolve the VSB API, to explain things to static checkers.

Poul-Henning Kamp phk at FreeBSD.org
Wed Aug 12 12:07:08 UTC 2020


commit 904659a1475a395c9972626670abbf0d2e4222f4
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Wed Aug 12 12:04:46 2020 +0000

    Evolve the VSB API, to explain things to static checkers.
    
    For dynamic allocations use:
    
            VSB_new_auto() + VSB_destroy()
    
    For preexisting buffers use:
    
            VSB_init() + VSB_fini()
    
    VSB_new + VSB_delete are deprecated.

diff --git a/bin/varnishd/cache/cache_backend_probe.c b/bin/varnishd/cache/cache_backend_probe.c
index 51fd00754..020ee1e75 100644
--- a/bin/varnishd/cache/cache_backend_probe.c
+++ b/bin/varnishd/cache/cache_backend_probe.c
@@ -256,7 +256,7 @@ vbp_write_proxy_v1(struct vbp_target *vt, int *sock)
 	socklen_t l;
 
 	VTCP_myname(*sock, addr, sizeof addr, port, sizeof port);
-	AN(VSB_new(&vsb, buf, sizeof buf, VSB_FIXEDLEN));
+	AN(VSB_init(&vsb, buf, sizeof buf));
 
 	l = sizeof ss;
 	AZ(getsockname(*sock, (void *)&ss, &l));
@@ -268,7 +268,8 @@ vbp_write_proxy_v1(struct vbp_target *vt, int *sock)
 		VSB_cat(&vsb, "PROXY UNKNOWN\r\n");
 	AZ(VSB_finish(&vsb));
 
-	return (vbp_write(vt, sock, VSB_data(&vsb), VSB_len(&vsb)));
+	VSB_fini(&vsb);
+	return (vbp_write(vt, sock, buf, strlen(buf)));
 }
 
 static void
diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c
index c59f35c53..19ae14a00 100644
--- a/bin/varnishd/cache/cache_panic.c
+++ b/bin/varnishd/cache/cache_panic.c
@@ -853,8 +853,7 @@ PAN_Init(void)
 	pan_vsb = &pan_vsb_storage;
 	AN(heritage.panic_str);
 	AN(heritage.panic_str_len);
-	AN(VSB_new(pan_vsb, heritage.panic_str, heritage.panic_str_len,
-	    VSB_FIXEDLEN));
+	AN(VSB_init(pan_vsb, heritage.panic_str, heritage.panic_str_len));
 	VSB_cat(pan_vsb, "This is a test\n");
 	AZ(VSB_finish(pan_vsb));
 	VSB_clear(pan_vsb);
diff --git a/bin/varnishd/cache/cache_ws.c b/bin/varnishd/cache/cache_ws.c
index dc1744779..874181436 100644
--- a/bin/varnishd/cache/cache_ws.c
+++ b/bin/varnishd/cache/cache_ws.c
@@ -393,12 +393,13 @@ WS_VSB_new(struct vsb *vsb, struct ws *ws)
 	unsigned u;
 	static char bogus[2];	// Smallest possible vsb
 
+	AN(vsb);
 	WS_Assert(ws);
 	u = WS_ReserveAll(ws);
 	if (WS_Overflowed(ws) || u < 2)
-		AN(VSB_new(vsb, bogus, sizeof bogus, VSB_FIXEDLEN));
+		AN(VSB_init(vsb, bogus, sizeof bogus));
 	else
-		AN(VSB_new(vsb, WS_Front(ws), u, VSB_FIXEDLEN));
+		AN(VSB_init(vsb, WS_Front(ws), u));
 }
 
 char *
@@ -406,6 +407,7 @@ WS_VSB_finish(struct vsb *vsb, struct ws *ws, size_t *szp)
 {
 	char *p;
 
+	AN(vsb);
 	WS_Assert(ws);
 	if (!VSB_finish(vsb)) {
 		p = VSB_data(vsb);
@@ -413,12 +415,12 @@ WS_VSB_finish(struct vsb *vsb, struct ws *ws, size_t *szp)
 			WS_Release(ws, VSB_len(vsb) + 1);
 			if (szp != NULL)
 				*szp = VSB_len(vsb);
-			VSB_delete(vsb);
+			VSB_fini(vsb);
 			return (p);
 		}
 	}
 	WS_MarkOverflow(ws);
-	VSB_delete(vsb);
+	VSB_fini(vsb);
 	WS_Release(ws, 0);
 	if (szp)
 		*szp = 0;
diff --git a/bin/varnishd/proxy/cache_proxy_proto.c b/bin/varnishd/proxy/cache_proxy_proto.c
index 1cc36d47f..ff9066e0d 100644
--- a/bin/varnishd/proxy/cache_proxy_proto.c
+++ b/bin/varnishd/proxy/cache_proxy_proto.c
@@ -725,7 +725,7 @@ VPX_Send_Proxy(int fd, int version, const struct sess *sp)
 
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 	assert(version == 1 || version == 2);
-	AN(VSB_new(vsb, buf, sizeof buf, VSB_FIXEDLEN));
+	AN(VSB_init(vsb, buf, sizeof buf));
 
 	AZ(SES_Get_server_addr(sp, &sas));
 	AN(sas);
@@ -756,6 +756,7 @@ VPX_Send_Proxy(int fd, int version, const struct sess *sp)
 	AZ(VSB_finish(vsb2));
 	VSL(SLT_Debug, 999, "PROXY_HDR %s", VSB_data(vsb2));
 	VSB_destroy(&vsb2);
+	VSB_fini(vsb);
 	return (r);
 }
 
diff --git a/include/vsb.h b/include/vsb.h
index facea9394..23d9dad82 100644
--- a/include/vsb.h
+++ b/include/vsb.h
@@ -59,9 +59,9 @@ extern "C" {
 /*
  * API functions
  */
-struct vsb	*VSB_new(struct vsb *, char *, int, int);
-#define		 VSB_new_auto()				\
-	VSB_new(NULL, NULL, 0, VSB_AUTOEXTEND)
+struct vsb	*VSB_new(struct vsb *, char *, int, int);	// DEPRECATED
+struct vsb	*VSB_init(struct vsb *, void *, ssize_t);
+struct vsb	*VSB_new_auto(void);
 void		 VSB_clear(struct vsb *);
 int		 VSB_bcat(struct vsb *, const void *, ssize_t);
 int		 VSB_cat(struct vsb *, const char *);
@@ -76,7 +76,8 @@ int		 VSB_error(const struct vsb *);
 int		 VSB_finish(struct vsb *);
 char		*VSB_data(const struct vsb *);
 ssize_t		 VSB_len(const struct vsb *);
-void		 VSB_delete(struct vsb *);
+void		 VSB_delete(struct vsb *);			// DEPRECATED
+void		 VSB_fini(struct vsb *);
 void		 VSB_destroy(struct vsb **);
 #define VSB_QUOTE_NONL		1
 #define VSB_QUOTE_JSON		2
diff --git a/lib/libvarnish/vin.c b/lib/libvarnish/vin.c
index 8f8d616dd..581bbdba2 100644
--- a/lib/libvarnish/vin.c
+++ b/lib/libvarnish/vin.c
@@ -69,7 +69,7 @@ VIN_n_Arg(const char *n_arg, char **dir)
 
 	/* Second: find the directory name */
 
-	AN(VSB_new(vsb, dn, sizeof dn, VSB_FIXEDLEN));
+	AN(VSB_init(vsb, dn, sizeof dn));
 
 	if (*nm == '/')
 		i = VSB_printf(vsb, "%s/", nm);
@@ -82,11 +82,11 @@ VIN_n_Arg(const char *n_arg, char **dir)
 	}
 
 	AZ(VSB_finish(vsb));
-	VSB_clear(vsb);
 
-	*dir = strdup(dn);
+	*dir = strdup(VSB_data(vsb));
 	if (*dir == NULL)
 		return (-1);
 
+	VSB_fini(vsb);
 	return (0);
 }
diff --git a/lib/libvarnish/vsb.c b/lib/libvarnish/vsb.c
index ef9f164b0..df007c445 100644
--- a/lib/libvarnish/vsb.c
+++ b/lib/libvarnish/vsb.c
@@ -236,6 +236,36 @@ VSB_new(struct vsb *s, char *buf, int length, int flags)
 	return (s);
 }
 
+struct vsb *
+VSB_init(struct vsb *s, void *buf, ssize_t length)
+{
+	AN(s);
+	AN(buf);
+
+	KASSERT(length >= 0,
+	    ("attempt to create an vsb of negative length (%zd)", length));
+	return (VSB_newbuf(s, buf, length, VSB_FIXEDLEN));
+}
+
+/*
+ * Allocate a dynamic vsb
+ */
+struct vsb *
+VSB_new_auto(void)
+{
+	struct vsb *s;
+
+	s = SBMALLOC(sizeof(*s));
+	if (s == NULL)
+		return (NULL);
+	if (VSB_newbuf(s, NULL, 0, VSB_AUTOEXTEND) == NULL) {
+		SBFREE(s);
+		return (NULL);
+	}
+	VSB_SETFLAG(s, VSB_DYNSTRUCT);
+	return (s);
+}
+
 /*
  * Clear an vsb and reset its position.
  */
@@ -493,10 +523,24 @@ VSB_delete(struct vsb *s)
 		SBFREE(s);
 }
 
+void
+VSB_fini(struct vsb *s)
+{
+
+	assert_VSB_integrity(s);
+	assert(!VSB_ISDYNAMIC(s));
+	memset(s, 0, sizeof(*s));
+}
+
 void
 VSB_destroy(struct vsb **s)
 {
-	VSB_delete(*s);
+
+	AN(s);
+	assert_VSB_integrity(*s);
+	assert(VSB_ISDYNAMIC(*s));
+	memset(*s, 0, sizeof(**s));
+	SBFREE(*s);
 	*s = NULL;
 }
 
diff --git a/lib/libvarnishapi/libvarnishapi.map b/lib/libvarnishapi/libvarnishapi.map
index 0ba4c8500..4436a9205 100644
--- a/lib/libvarnishapi/libvarnishapi.map
+++ b/lib/libvarnishapi/libvarnishapi.map
@@ -185,3 +185,13 @@ LIBVARNISHAPI_2.4 {	/* 2020-03-15 release */
     local:
 	*;
 };
+
+LIBVARNISHAPI_2.5 {	/* 2020-09-15 release */
+    global:
+	# vsb.c
+	VSB_init;
+	VSB_fini;
+	VSB_new_auto;
+    local:
+	*;
+};
diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c
index 182cff8e1..1447ec2b3 100644
--- a/lib/libvcc/vcc_expr.c
+++ b/lib/libvcc/vcc_expr.c
@@ -1085,13 +1085,14 @@ cmp_regexp(struct vcc *tl, struct expr **e, const struct cmps *cp)
 	*e = vcc_expr_edit(tl, STRING, "\vS", *e, NULL);
 	vcc_NextToken(tl);
 	ExpectErr(tl, CSTR);
-	AN(VSB_new(&vsb, buf, sizeof buf, VSB_FIXEDLEN));
+	AN(VSB_init(&vsb, buf, sizeof buf));
 	VSB_printf(&vsb, "%sVRT_re_match(ctx, \v1, ", cp->emit);
 	vcc_regexp(tl, &vsb);
 	ERRCHK(tl);
 	VSB_cat(&vsb, ")");
 	AZ(VSB_finish(&vsb));
 	*e = vcc_expr_edit(tl, BOOL, VSB_data(&vsb), *e, NULL);
+	VSB_fini(&vsb);
 }
 
 static void v_matchproto_(cmp_f)
@@ -1473,12 +1474,13 @@ vcc_Eval_Regsub(struct vcc *tl, struct expr **e, struct token *t,
 	SkipToken(tl, ',');
 	ExpectErr(tl, CSTR);
 
-	AN(VSB_new(&vsb, buf, sizeof buf, VSB_FIXEDLEN));
+	AN(VSB_init(&vsb, buf, sizeof buf));
 	VSB_printf(&vsb, "VRT_regsub(ctx, %d,\v+\n\v1,\n", all);
 	vcc_regexp(tl, &vsb);
 	ERRCHK(tl);
 	AZ(VSB_finish(&vsb));
 	*e = vcc_expr_edit(tl, STRING, VSB_data(&vsb), e2, NULL);
+	VSB_fini(&vsb);
 	SkipToken(tl, ',');
 	vcc_expr0(tl, &e2, STRING);
 	ERRCHK(tl);


More information about the varnish-commit mailing list