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
See LICENSE
......@@ -10,6 +10,8 @@ varnish v1 -arg "-p vcc_err_unref=off" -vcl {
new s = dispatch.sub();
s.add(0, "sub1");
s.add(1, "sub2");
s.add(2, "sub_underscore");
s.add(3, "sub-hyphen");
}
sub sub1 {
......@@ -20,13 +22,30 @@ varnish v1 -arg "-p vcc_err_unref=off" -vcl {
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 {
if (req.url == "/0") {
s.call(0);
}
if (req.url == "/1") {
elsif (req.url == "/1") {
s.call(1);
}
elsif (req.url == "/2") {
s.call(2);
}
elsif (req.url == "/3") {
s.call(3);
}
else {
return(fail);
}
return(synth(200));
}
......@@ -44,6 +63,14 @@ client c1 {
rxresp
expect resp.status == 200
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
varnish v1 -errvcl {vmod dispatch error: s.add(0): subroutine name is empty} {
......
......@@ -34,6 +34,8 @@
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <ctype.h>
#include <stdio.h>
#include "cache/cache.h"
#include "vcl.h"
......@@ -49,6 +51,9 @@
#define INIT_BITS (64)
#define CFUNC_PREFIX ("VGC_function_")
#define CFUNC_PREFIX_LEN (sizeof(CFUNC_PREFIX) - 1)
struct vmod_dispatch_label {
unsigned magic;
#define VMOD_DISPATCH_LABEL_MAGIC 0x44515cd0
......@@ -236,9 +241,9 @@ VCL_VOID
vmod_sub_add(VRT_CTX, struct vmod_dispatch_sub *sub, VCL_INT n,
VCL_STRING subname)
{
uintptr_t snap;
struct vmod_dispatch_vcl *vcl;
char *funcname;
char *funcname, *f;
unsigned len, l = 0;
vcl_func_f *vcl_func;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
......@@ -260,18 +265,50 @@ vmod_sub_add(VRT_CTX, struct vmod_dispatch_sub *sub, VCL_INT n,
n, subname);
return;
}
snap = WS_Snapshot(ctx->ws);
if ((funcname = WS_Printf(ctx->ws, "VGC_function_%s", subname))
== NULL) {
len = WS_Reserve(ctx->ws, 0);
if (len <= CFUNC_PREFIX_LEN) {
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 "
"internal C function name", sub->vcl_name, n, subname);
WS_Release(ctx->ws, 0);
return;
}
funcname[CFUNC_PREFIX_LEN + l] = '\0';
vcl_func = dlsym(vcl->dlh, funcname);
WS_Reset(ctx->ws, snap);
WS_Release(ctx->ws, 0);
if (vcl_func == NULL) {
VERR(ctx, "%s.add(%ld, %s): VCL subroutine not found: %s",
sub->vcl_name, n, subname, dlerror());
VERR(ctx, "%s.add(%ld, %s): VCL subroutine not found "
"(C function %s): %s", sub->vcl_name, n, subname, funcname,
dlerror());
return;
}
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