[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