[4.1] 2bb8dde Properly encode HTTP headers with weird characters to C identifiers.

Poul-Henning Kamp phk at FreeBSD.org
Fri Sep 4 15:54:52 CEST 2015


commit 2bb8ddef13e988216d58b2ed16f40e34db36a0cb
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Aug 3 06:59:20 2015 +0000

    Properly encode HTTP headers with weird characters to C identifiers.
    
    Please note that using underscore in HTTP headers is considered a
    really bad idea because many application frameworks map minus to
    underscore in environment variables.
    
    Fixes: 	#1768

diff --git a/bin/varnishtest/tests/r01768.vtc b/bin/varnishtest/tests/r01768.vtc
new file mode 100644
index 0000000..716701a
--- /dev/null
+++ b/bin/varnishtest/tests/r01768.vtc
@@ -0,0 +1,19 @@
+varnishtest "http header collision -/_"
+
+server s1 {
+	rxreq
+	txresp
+} -start
+
+varnish v1 -vcl+backend {
+	sub vcl_recv {
+		if (req.http.foo_bar == req.http.foo-bar) {
+			set req.http.foo_bar = "xxx";
+		}
+	}
+} -start
+
+client c1 {
+	txreq
+	rxresp
+} -run
diff --git a/lib/libvcc/vcc_var.c b/lib/libvcc/vcc_var.c
index 0fd45ec..a018f36 100644
--- a/lib/libvcc/vcc_var.c
+++ b/lib/libvcc/vcc_var.c
@@ -43,43 +43,43 @@ vcc_Var_Wildcard(struct vcc *tl, const struct token *t, const struct symbol *wc)
 	struct symbol *sym;
 	struct var *v;
 	const struct var *vh;
-	int l, i;
-	char c;
-	char buf[258];
-	char cnam[256];
+	unsigned u;
+	const char *p, *leaf;
+	struct vsb *vsb;
 
 	vh = wc->var;
+	assert(vh->fmt == HEADER);
 
 	v = TlAlloc(tl, sizeof *v);
 	AN(v);
-
-	assert(vh->fmt == HEADER);
 	v->name = TlDupTok(tl, t);
 	v->r_methods = vh->r_methods;
 	v->w_methods = vh->w_methods;
 	v->fmt = vh->fmt;
+	leaf = v->name + vh->len;
 
 	/* Create a C-name version of the header name */
-	l = strlen(v->name + vh->len) + 1;
-	for (i = 0; i < l - 1; i++) {
-		c = *(v->name + vh->len + i);
-		if (vct_isalpha(c) || vct_isdigit(c))
-			cnam[i] = c;
+	vsb = VSB_new_auto();
+	AN(vsb);
+	VSB_printf(vsb, "&VGC_%s_", vh->rname);
+	for (p = leaf, u = 1; *p != '\0'; p++, u++)
+		if (vct_isalpha(*p) || vct_isdigit(*p))
+			VSB_putc(vsb, *p);
 		else
-			cnam[i] = '_';
-	}
-	cnam[i] = '\0';
+			VSB_printf(vsb, "_%02x_", *p);
+	AZ(VSB_finish(vsb));
 
 	/* Create the static identifier */
-	Fh(tl, 0, "static const struct gethdr_s VGC_%s_%s =\n",
-	    vh->rname, cnam);
-	Fh(tl, 0, "    { %s, \"\\%03o%s:\"};\n",
-	    vh->rname, (unsigned)l, v->name + vh->len);
-
-	bprintf(buf, "&VGC_%s_%s", vh->rname, cnam);
-	v->rname = TlDup(tl, buf);
-	bprintf(buf, "VRT_SetHdr(ctx, %s,", v->rname);
-	v->lname = TlDup(tl, buf);
+	Fh(tl, 0, "static const struct gethdr_s %s =\n", VSB_data(vsb) + 1);
+	Fh(tl, 0, "    { %s, \"\\%03o%s:\"};\n", vh->rname, u, leaf);
+
+	/* Create the symbol r/l values */
+	v->rname = TlDup(tl, VSB_data(vsb));
+	VSB_clear(vsb);
+	VSB_printf(vsb, "VRT_SetHdr(ctx, %s,", v->rname);
+	AZ(VSB_finish(vsb));
+	v->lname = TlDup(tl, VSB_data(vsb));
+	VSB_delete(vsb);
 
 	sym = VCC_AddSymbolTok(tl, t, SYM_VAR);
 	AN(sym);



More information about the varnish-commit mailing list