Commit a465de3f authored by Geoff Simmons's avatar Geoff Simmons

Bugfix sub object for subroutine names with non-alphanum characters.

These are formatted as for VCC_PrintCName() in libvcc.
parent 8ead94e1
Pipeline #396 skipped
...@@ -155,4 +155,3 @@ COPYRIGHT ...@@ -155,4 +155,3 @@ COPYRIGHT
See LICENSE See LICENSE
...@@ -10,6 +10,8 @@ varnish v1 -arg "-p vcc_err_unref=off" -vcl { ...@@ -10,6 +10,8 @@ varnish v1 -arg "-p vcc_err_unref=off" -vcl {
new s = dispatch.sub(); new s = dispatch.sub();
s.add(0, "sub1"); s.add(0, "sub1");
s.add(1, "sub2"); s.add(1, "sub2");
s.add(2, "sub_underscore");
s.add(3, "sub-hyphen");
} }
sub sub1 { sub sub1 {
...@@ -20,13 +22,30 @@ varnish v1 -arg "-p vcc_err_unref=off" -vcl { ...@@ -20,13 +22,30 @@ varnish v1 -arg "-p vcc_err_unref=off" -vcl {
set req.http.Sub = "sub2"; set req.http.Sub = "sub2";
} }
sub sub_underscore {
set req.http.Sub = "sub_underscore";
}
sub sub-hyphen {
set req.http.Sub = "sub-hyphen";
}
sub vcl_recv { sub vcl_recv {
if (req.url == "/0") { if (req.url == "/0") {
s.call(0); s.call(0);
} }
if (req.url == "/1") { elsif (req.url == "/1") {
s.call(1); s.call(1);
} }
elsif (req.url == "/2") {
s.call(2);
}
elsif (req.url == "/3") {
s.call(3);
}
else {
return(fail);
}
return(synth(200)); return(synth(200));
} }
...@@ -44,6 +63,14 @@ client c1 { ...@@ -44,6 +63,14 @@ client c1 {
rxresp rxresp
expect resp.status == 200 expect resp.status == 200
expect resp.http.Sub == "sub2" expect resp.http.Sub == "sub2"
txreq -url "/2"
rxresp
expect resp.status == 200
expect resp.http.Sub == "sub_underscore"
txreq -url "/3"
rxresp
expect resp.status == 200
expect resp.http.Sub == "sub-hyphen"
} -run } -run
varnish v1 -errvcl {vmod dispatch error: s.add(0): subroutine name is empty} { varnish v1 -errvcl {vmod dispatch error: s.add(0): subroutine name is empty} {
......
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <ctype.h>
#include <stdio.h>
#include "cache/cache.h" #include "cache/cache.h"
#include "vcl.h" #include "vcl.h"
...@@ -49,6 +51,9 @@ ...@@ -49,6 +51,9 @@
#define INIT_BITS (64) #define INIT_BITS (64)
#define CFUNC_PREFIX ("VGC_function_")
#define CFUNC_PREFIX_LEN (sizeof(CFUNC_PREFIX) - 1)
struct vmod_dispatch_label { struct vmod_dispatch_label {
unsigned magic; unsigned magic;
#define VMOD_DISPATCH_LABEL_MAGIC 0x44515cd0 #define VMOD_DISPATCH_LABEL_MAGIC 0x44515cd0
...@@ -236,9 +241,9 @@ VCL_VOID ...@@ -236,9 +241,9 @@ VCL_VOID
vmod_sub_add(VRT_CTX, struct vmod_dispatch_sub *sub, VCL_INT n, vmod_sub_add(VRT_CTX, struct vmod_dispatch_sub *sub, VCL_INT n,
VCL_STRING subname) VCL_STRING subname)
{ {
uintptr_t snap;
struct vmod_dispatch_vcl *vcl; struct vmod_dispatch_vcl *vcl;
char *funcname; char *funcname, *f;
unsigned len, l = 0;
vcl_func_f *vcl_func; vcl_func_f *vcl_func;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
...@@ -260,18 +265,50 @@ vmod_sub_add(VRT_CTX, struct vmod_dispatch_sub *sub, VCL_INT n, ...@@ -260,18 +265,50 @@ vmod_sub_add(VRT_CTX, struct vmod_dispatch_sub *sub, VCL_INT n,
n, subname); n, subname);
return; return;
} }
snap = WS_Snapshot(ctx->ws); len = WS_Reserve(ctx->ws, 0);
if ((funcname = WS_Printf(ctx->ws, "VGC_function_%s", subname)) if (len <= CFUNC_PREFIX_LEN) {
== NULL) { VERR(ctx, "%s.add(%ld, %s): insufficient workspace for "
"internal C function prefix", sub->vcl_name, n, subname);
WS_Release(ctx->ws, 0);
return;
}
funcname = WS_Front(ctx->ws);
strcpy(funcname, CFUNC_PREFIX);
f = funcname + CFUNC_PREFIX_LEN;
/* cf. VCC_PrintCName() */
for (const char *s = subname; *s; s++) {
if (*s < 0 || !isalnum(*s)) {
if (l + 4 >= len) {
l = 0;
break;
}
sprintf(f, "_%02x_", *s);
f += 4;
l += 4;
}
else {
if (l == len) {
l = 0;
break;
}
*f++ = *s;
l++;
}
}
if (l == 0) {
VERR(ctx, "%s.add(%ld, %s): insufficient workspace for " VERR(ctx, "%s.add(%ld, %s): insufficient workspace for "
"internal C function name", sub->vcl_name, n, subname); "internal C function name", sub->vcl_name, n, subname);
WS_Release(ctx->ws, 0);
return; return;
} }
funcname[CFUNC_PREFIX_LEN + l] = '\0';
vcl_func = dlsym(vcl->dlh, funcname); vcl_func = dlsym(vcl->dlh, funcname);
WS_Reset(ctx->ws, snap); WS_Release(ctx->ws, 0);
if (vcl_func == NULL) { if (vcl_func == NULL) {
VERR(ctx, "%s.add(%ld, %s): VCL subroutine not found: %s", VERR(ctx, "%s.add(%ld, %s): VCL subroutine not found "
sub->vcl_name, n, subname, dlerror()); "(C function %s): %s", sub->vcl_name, n, subname, funcname,
dlerror());
return; return;
} }
if (n >= sub->nsubs) if (n >= sub->nsubs)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment