[master] 51a117587 Give struct strands a magic value

Nils Goroll nils.goroll at uplex.de
Mon Jul 21 13:57:02 UTC 2025


commit 51a117587524cbdd59e43567e6cbd5a76e6a39ff
Author: Nils Goroll <nils.goroll at uplex.de>
Date:   Wed Jul 9 09:10:43 2025 +0200

    Give struct strands a magic value
    
    On 64bit, this basically comes for free because the pointer p is already aligned
    on 8 bytes.
    
    Motivated by the void pointer type VCL_BODY, which is basically a union of a
    blob and a struct strands.
    
    Magic checks follow the rule:
    
    - If a function accesses the object, add a check
    - If a function only passes on the object, don't

diff --git a/bin/varnishd/cache/cache_shmlog.c b/bin/varnishd/cache/cache_shmlog.c
index ee671afd9..e2c6e1626 100644
--- a/bin/varnishd/cache/cache_shmlog.c
+++ b/bin/varnishd/cache/cache_shmlog.c
@@ -53,6 +53,7 @@ strands_len(const struct strands *s)
 	unsigned r = 0;
 	int i;
 
+	CHECK_OBJ_NOTNULL(s, STRANDS_MAGIC);
 	for (i = 0; i < s->n; i++) {
 		if (s->p[i] == NULL || *s->p[i] == '\0')
 			continue;
@@ -76,6 +77,7 @@ strands_cat(char *buf, unsigned bufl, const struct strands *s)
 	/* NUL-terminated */
 	assert(bufl > 0);
 	bufl--;
+	CHECK_OBJ_NOTNULL(s, STRANDS_MAGIC);
 
 	for (i = 0; i < s->n && bufl > 0; i++) {
 		if (s->p[i] == NULL || *s->p[i] == '\0')
diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c
index e2bd090d8..edec7d64f 100644
--- a/bin/varnishd/cache/cache_vrt.c
+++ b/bin/varnishd/cache/cache_vrt.c
@@ -56,6 +56,7 @@
 
 // NOT using TOSTRANDS() to create a NULL pointer element despite n == 0
 const struct strands *const vrt_null_strands = &(struct strands){
+	.magic = STRANDS_MAGIC,
 	.n = 0,
 	.p = (const char *[1]){NULL}
 };
@@ -307,6 +308,7 @@ VRT_AllocStrandsWS(struct ws *ws, int n)
 	if (s == NULL || p == NULL)
 		return (NULL);
 
+	s->magic = STRANDS_MAGIC;
 	s->n = n;
 	s->p = p;
 
@@ -323,6 +325,9 @@ VRT_CompareStrands(VCL_STRANDS a, VCL_STRANDS b)
 	const char *pa = NULL, *pb = NULL;
 	int na = 0, nb = 0;
 
+	CHECK_OBJ_NOTNULL(a, STRANDS_MAGIC);
+	CHECK_OBJ_NOTNULL(b, STRANDS_MAGIC);
+
 	while (1) {
 		if (pa != NULL && *pa == '\0')
 			pa = NULL;
@@ -360,7 +365,7 @@ VRT_Strands2Bool(VCL_STRANDS s)
 {
 	int i;
 
-	AN(s);
+	CHECK_OBJ_NOTNULL(s, STRANDS_MAGIC);
 	for (i = 0; i < s->n; i++)
 		if (s->p[i] != NULL)
 			return (1);
@@ -379,7 +384,7 @@ VRT_HashStrands32(VCL_STRANDS s)
 	const char *p;
 	int i;
 
-	AN(s);
+	CHECK_OBJ_NOTNULL(s, STRANDS_MAGIC);
 	VSHA256_Init(&sha_ctx);
 	for (i = 0; i < s->n; i++) {
 		p = s->p[i];
@@ -409,7 +414,7 @@ VRT_Strands(char *d, size_t dl, VCL_STRANDS s)
 	unsigned x;
 
 	AN(d);
-	AN(s);
+	CHECK_OBJ_NOTNULL(s, STRANDS_MAGIC);
 	b = d;
 	e = b + dl;
 	for (int i = 0; i < s->n; i++)
@@ -437,7 +442,7 @@ VRT_StrandsWS(struct ws *ws, const char *h, VCL_STRANDS s)
 	int i;
 
 	WS_Assert(ws);
-	AN(s);
+	CHECK_OBJ_NOTNULL(s, STRANDS_MAGIC);
 
 	for (i = 0; i < s->n; i++) {
 		if (s->p[i] != NULL && *s->p[i] != '\0') {
@@ -502,7 +507,7 @@ VRT_UpperLowerStrands(VRT_CTX, VCL_STRANDS s, int up)
 
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
 	CHECK_OBJ_NOTNULL(ctx->ws, WS_MAGIC);
-	AN(s);
+	CHECK_OBJ_NOTNULL(s, STRANDS_MAGIC);
 	u = WS_ReserveAll(ctx->ws);
 	r = b = WS_Reservation(ctx->ws);
 	e = b + u;
@@ -566,6 +571,7 @@ VRT_ValidHdr(VRT_CTX, VCL_STRANDS s)
 
 	(void) ctx;
 
+	CHECK_OBJ_NOTNULL(s, STRANDS_MAGIC);
 	for (i = 0; i < s->n; i++) {
 		if (s->p[i] == NULL || s->p[i][0] == '\0')
 			continue;
@@ -713,7 +719,7 @@ VRT_hashdata(VRT_CTX, VCL_STRANDS s)
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
 	CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
 	AN(ctx->specific);
-	AN(s);
+	CHECK_OBJ_NOTNULL(s, STRANDS_MAGIC);
 	for (i = 0; i < s->n; i++)
 		HSH_AddString(ctx->req, ctx->specific, s->p[i]);
 	/*
@@ -867,7 +873,7 @@ VRT_synth_strands(VRT_CTX, VCL_STRANDS s)
 	int i;
 
 	CAST_OBJ_NOTNULL(vsb, ctx->specific, VSB_MAGIC);
-	AN(s);
+	CHECK_OBJ_NOTNULL(s, STRANDS_MAGIC);
 	for (i = 0; i < s->n; i++) {
 		if (s->p[i] != NULL)
 			VSB_cat(vsb, s->p[i]);
diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c
index bf44efca8..b01b97460 100644
--- a/bin/varnishd/cache/cache_vrt_var.c
+++ b/bin/varnishd/cache/cache_vrt_var.c
@@ -1088,6 +1088,7 @@ VRT_l_##which##_body(VRT_CTX, enum lbody_e type,		\
 	assert(type == LBODY_SET_STRING ||			\
 	    type == LBODY_ADD_STRING);				\
 	s = body;						\
+	CHECK_OBJ_NOTNULL(s, STRANDS_MAGIC);			\
 	for (n = 0; s != NULL && n < s->n; n++)			\
 		if (s->p[n] != NULL)				\
 			VSB_cat(vsb, s->p[n]);			\
diff --git a/bin/varnishtest/tests/r01406.vtc b/bin/varnishtest/tests/r01406.vtc
index 76af91952..14de8bf04 100644
--- a/bin/varnishtest/tests/r01406.vtc
+++ b/bin/varnishtest/tests/r01406.vtc
@@ -19,8 +19,7 @@ varnish v1 -arg "-p vcc_feature=+allow_inline_c" -vcl+backend {
 			    ctx,
 			    &VGC_HDR_REQ_foo,
 			    0,
-			    &(struct strands){.n = 0}
-			);
+			    vrt_null_strands);
 		}C
 	}
 
diff --git a/include/vrt.h b/include/vrt.h
index 26f5aa8d6..730df304a 100644
--- a/include/vrt.h
+++ b/include/vrt.h
@@ -87,6 +87,7 @@
  *	VRT_RemoveVFP() removed
  *	VRT_RemoveVDP() removed
  *	struct vrt_blob magic added
+ *	struct strands magic added;
  * 21.0 (2025-03-17)
  *	VRT_u_req_grace() added
  *	VRT_u_req_ttl() added
@@ -373,6 +374,8 @@ typedef const struct stream_close *stream_close_t;
  */
 
 struct strands {
+	unsigned	magic;
+#define STRANDS_MAGIC	0x5d5ab196
 	int		n;
 	const char	**p;
 };
@@ -385,8 +388,10 @@ extern const struct strands *const vrt_null_strands;
 /*
  * Macros for VCL_STRANDS creation
  */
-#define TOSTRAND(s)(&(struct strands){.n=1,.p=(const char *[1]){(s)}})
-#define TOSTRANDS(x, ...)(&(struct strands){.n=x,.p=(const char *[x]){__VA_ARGS__}})
+#define TOSTRAND(s)(&(struct strands)				\
+	{.magic=STRANDS_MAGIC,.n=1,.p=(const char *[1]){(s)}})
+#define TOSTRANDS(x, ...)(&(struct strands)			\
+	{.magic=STRANDS_MAGIC,.n=x,.p=(const char *[x]){__VA_ARGS__}})
 
 /***********************************************************************
  * VCL_BLOB:
diff --git a/vmod/vmod_blob.c b/vmod/vmod_blob.c
index 122a97c5b..31d70687f 100644
--- a/vmod/vmod_blob.c
+++ b/vmod/vmod_blob.c
@@ -144,6 +144,7 @@ decode_l(enum encoding dec, VCL_STRANDS s)
 
 	AENC(dec);
 
+	CHECK_OBJ_NOTNULL(s, STRANDS_MAGIC);
 	for (int i = 0; i < s->n; i++)
 		if (s->p[i] != NULL && *s->p[i] != '\0')
 			len += strlen(s->p[i]);
@@ -201,7 +202,7 @@ vmod_blob__init(VRT_CTX, struct vmod_blob_blob **blobp, const char *vcl_name,
 	AZ(*blobp);
 	AN(vcl_name);
 	AENC(dec);
-	AN(strings);
+	CHECK_OBJ_NOTNULL(strings, STRANDS_MAGIC);
 
 	ALLOC_OBJ(b, VMOD_BLOB_MAGIC);
 	AN(b);
@@ -344,7 +345,7 @@ vmod_decode(VRT_CTX, VCL_ENUM decs, VCL_INT length, VCL_STRANDS strings)
 
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
 	AENC(dec);
-	AN(strings);
+	CHECK_OBJ_NOTNULL(strings, STRANDS_MAGIC);
 	CHECK_OBJ_NOTNULL(ctx->ws, WS_MAGIC);
 
 	space = WS_ReserveAll(ctx->ws);
@@ -430,7 +431,7 @@ vmod_transcode(VRT_CTX, VCL_ENUM decs, VCL_ENUM encs, VCL_ENUM case_s,
 
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
 	CHECK_OBJ_NOTNULL(ctx->ws, WS_MAGIC);
-	AN(strings);
+	CHECK_OBJ_NOTNULL(strings, STRANDS_MAGIC);
 
 	AENC(dec);
 	AENC(enc);
diff --git a/vmod/vmod_blob_base64.c b/vmod/vmod_blob_base64.c
index 971a05e91..c22935654 100644
--- a/vmod/vmod_blob_base64.c
+++ b/vmod/vmod_blob_base64.c
@@ -33,6 +33,7 @@
 #include "vdef.h"
 #include "vrt.h"
 #include "vas.h"
+#include "miniobj.h"
 
 #include "vmod_blob.h"
 
@@ -308,7 +309,7 @@ base64_decode(const enum encoding dec, blob_dest_t buf,
 
 	AN(buf);
 	AN(alpha);
-	AN(strings);
+	CHECK_OBJ_NOTNULL(strings, STRANDS_MAGIC);
 
 	if (inlen >= 0)
 		len = inlen;
diff --git a/vmod/vmod_blob_hex.c b/vmod/vmod_blob_hex.c
index b11701940..dedfc4557 100644
--- a/vmod/vmod_blob_hex.c
+++ b/vmod/vmod_blob_hex.c
@@ -35,6 +35,7 @@
 #include "vdef.h"
 #include "vrt.h"
 #include "vas.h"
+#include "miniobj.h"
 
 #include "vmod_blob.h"
 
@@ -113,7 +114,7 @@ hex_decode(const enum encoding dec, blob_dest_t buf,
 	int i;
 
 	AN(buf);
-	AN(strings);
+	CHECK_OBJ_NOTNULL(strings, STRANDS_MAGIC);
 	assert(dec == HEX);
 
 	for (i = 0; i < strings->n; i++) {
diff --git a/vmod/vmod_blob_id.c b/vmod/vmod_blob_id.c
index ad6b64607..1ef2e6985 100644
--- a/vmod/vmod_blob_id.c
+++ b/vmod/vmod_blob_id.c
@@ -35,6 +35,7 @@
 #include "vdef.h"
 #include "vrt.h"
 #include "vas.h"
+#include "miniobj.h"
 
 #include "vmod_blob.h"
 
@@ -79,7 +80,7 @@ id_decode(const enum encoding enc, blob_dest_t buf,
 
 	(void)enc;
 	AN(buf);
-	AN(strings);
+	CHECK_OBJ_NOTNULL(strings, STRANDS_MAGIC);
 
 	if (n >= 0)
 		c = n;
diff --git a/vmod/vmod_blob_url.c b/vmod/vmod_blob_url.c
index 9ce272ed8..4b21f0484 100644
--- a/vmod/vmod_blob_url.c
+++ b/vmod/vmod_blob_url.c
@@ -33,6 +33,7 @@
 #include "vdef.h"
 #include "vrt.h"
 #include "vas.h"
+#include "miniobj.h"
 
 #include "vmod_blob.h"
 
@@ -127,7 +128,7 @@ url_decode(const enum encoding dec, blob_dest_t buf,
 	int i;
 
 	AN(buf);
-	AN(strings);
+	CHECK_OBJ_NOTNULL(strings, STRANDS_MAGIC);
 	assert(dec == URL);
 
 	if (n >= 0)
diff --git a/vmod/vmod_debug.c b/vmod/vmod_debug.c
index 5fac83db3..bdf11deaf 100644
--- a/vmod/vmod_debug.c
+++ b/vmod/vmod_debug.c
@@ -683,6 +683,7 @@ xyzzy_sethdr(VRT_CTX, VCL_HEADER hdr, VCL_STRANDS s)
 	}
 	AN(hdr->what);
 	CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
+	CHECK_OBJ_NOTNULL(s, STRANDS_MAGIC);
 	if (s->n == 0) {
 		http_Unset(hp, hdr->what);
 	} else {
@@ -1365,6 +1366,7 @@ xyzzy_log_strands(VRT_CTX, VCL_STRING prefix, VCL_STRANDS subject, VCL_INT nn)
 	else
 		n = nn;
 
+	CHECK_OBJ_NOTNULL(subject, STRANDS_MAGIC);
 	for (i = 0; i < subject->n; i++) {
 		const char *p = subject->p[i];
 		mylog(ctx->vsl, SLT_Debug, "%s[%d]: (%s) %p %.*s%s", prefix, i,
diff --git a/vmod/vmod_directors_hash.c b/vmod/vmod_directors_hash.c
index fd8d42ab2..de131abe8 100644
--- a/vmod/vmod_directors_hash.c
+++ b/vmod/vmod_directors_hash.c
@@ -127,7 +127,6 @@ vmod_hash_backend(VRT_CTX, struct vmod_directors_hash *rr, VCL_STRANDS s)
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
 	CHECK_OBJ_ORNULL(ctx->bo, BUSYOBJ_MAGIC);
 	CHECK_OBJ_NOTNULL(rr, VMOD_DIRECTORS_HASH_MAGIC);
-	AN(s);
 
 	r = VRT_HashStrands32(s);
 	r = scalbn(r, -32);
diff --git a/vmod/vmod_std.c b/vmod/vmod_std.c
index c0c59122e..b2c9566b7 100644
--- a/vmod/vmod_std.c
+++ b/vmod/vmod_std.c
@@ -86,6 +86,7 @@ vmod_updown(VRT_CTX, int up, VCL_STRANDS s)
 	int i;
 
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+	CHECK_OBJ_NOTNULL(s, STRANDS_MAGIC);
 	u = WS_ReserveAll(ctx->ws);
 	e = b = WS_Reservation(ctx->ws);
 	e += u;
diff --git a/vmod/vmod_vtc.c b/vmod/vmod_vtc.c
index ace8728c3..2115fca30 100644
--- a/vmod/vmod_vtc.c
+++ b/vmod/vmod_vtc.c
@@ -493,6 +493,7 @@ vmod_vsl_replay(VRT_CTX, VCL_STRANDS s)
 	size_t l;
 	int i, err = 0;
 
+	CHECK_OBJ_ORNULL(s, STRANDS_MAGIC);
 	if (s == NULL || s->n == 0)
 		return;
 


More information about the varnish-commit mailing list