Commit db66dd1a authored by Geoff Simmons's avatar Geoff Simmons

restrict usages of functions that require a workspace to VCL subs in

which a workspace is available
parent b3bf1187
# looks like -*- perl -*-
varnishtest "test permitted use of functions in vcl_subs"
varnish v1 -vcl { backend b { .host="${bad_ip}"; } } -start
varnish v1 -errvcl {vmod convert error: decode() is illegal in vcl_init() and vcl_fini().vmod convert error: encode() is illegal in vcl_init() and vcl_fini().} {
import convert from "${vmod_topbuild}/src/.libs/libvmod_convert.so";
backend b { .host="${bad_ip}"; }
sub vcl_init {
new err = convert.blob(IDENTITY,
convert.encode(IDENTITY,
convert.decode(IDENTITY, "x")));
}
}
varnish v1 -errvcl {vmod convert error: transcode() is illegal in vcl_init() and vcl_fini().} {
import convert from "${vmod_topbuild}/src/.libs/libvmod_convert.so";
backend b { .host="${bad_ip}"; }
sub vcl_init {
new err = convert.blob(IDENTITY,
convert.transcode(IDENTITY, IDENTITY, "x"));
}
}
varnish v1 -errvcl {vmod convert error: encode() is illegal in vcl_init() and vcl_fini().} {
import convert from "${vmod_topbuild}/src/.libs/libvmod_convert.so";
backend b { .host="${bad_ip}"; }
sub vcl_init {
new b1 = convert.blob(IDENTITY, "foo");
new b2 = convert.blob(IDENTITY, convert.encode(IDENTITY, b1.get()));
}
}
# The *code() functions are legal in every other VCL sub
varnish v1 -vcl {
import convert from "${vmod_topbuild}/src/.libs/libvmod_convert.so";
backend b { .host="${bad_ip}"; }
sub vcl_recv {
set req.http.x = convert.encode(IDENTITY,
convert.decode(IDENTITY, "foo"));
set req.http.x = convert.transcode(IDENTITY, IDENTITY, "foo");
}
sub vcl_pipe {
set req.http.x = convert.encode(IDENTITY,
convert.decode(IDENTITY, "foo"));
set req.http.x = convert.transcode(IDENTITY, IDENTITY, "foo");
}
sub vcl_pass {
set req.http.x = convert.encode(IDENTITY,
convert.decode(IDENTITY, "foo"));
set req.http.x = convert.transcode(IDENTITY, IDENTITY, "foo");
}
sub vcl_hash {
set req.http.x = convert.encode(IDENTITY,
convert.decode(IDENTITY, "foo"));
set req.http.x = convert.transcode(IDENTITY, IDENTITY, "foo");
}
sub vcl_miss {
set req.http.x = convert.encode(IDENTITY,
convert.decode(IDENTITY, "foo"));
set req.http.x = convert.transcode(IDENTITY, IDENTITY, "foo");
}
sub vcl_hit {
set req.http.x = convert.encode(IDENTITY,
convert.decode(IDENTITY, "foo"));
set req.http.x = convert.transcode(IDENTITY, IDENTITY, "foo");
}
sub vcl_purge {
set req.http.x = convert.encode(IDENTITY,
convert.decode(IDENTITY, "foo"));
set req.http.x = convert.transcode(IDENTITY, IDENTITY, "foo");
}
sub vcl_deliver {
set req.http.x = convert.encode(IDENTITY,
convert.decode(IDENTITY, "foo"));
set req.http.x = convert.transcode(IDENTITY, IDENTITY, "foo");
}
sub vcl_synth {
set req.http.x = convert.encode(IDENTITY,
convert.decode(IDENTITY, "foo"));
set req.http.x = convert.transcode(IDENTITY, IDENTITY, "foo");
}
sub vcl_backend_fetch {
set bereq.http.x = convert.encode(IDENTITY,
convert.decode(IDENTITY, "foo"));
set bereq.http.x = convert.transcode(IDENTITY, IDENTITY, "foo");
}
sub vcl_backend_response {
set bereq.http.x = convert.encode(IDENTITY,
convert.decode(IDENTITY, "foo"));
set bereq.http.x = convert.transcode(IDENTITY, IDENTITY, "foo");
}
sub vcl_backend_error {
set bereq.http.x = convert.encode(IDENTITY,
convert.decode(IDENTITY, "foo"));
set bereq.http.x = convert.transcode(IDENTITY, IDENTITY, "foo");
}
}
......@@ -57,6 +57,11 @@ struct vmod_convert_blob {
#define ERRNOMEM(ctx, msg) \
ERR((ctx), msg ", out of space")
#define INIT_FINI(ctx) (((ctx)->method & (VCL_MET_INIT | VCL_MET_FINI)) != 0)
#define ILLEGAL(ctx, m) \
ERR((ctx), m " is illegal in vcl_init() and vcl_fini().")
static const struct vmod_priv const null_blob[1] =
{
{
......@@ -182,10 +187,11 @@ errmsg(VRT_CTX, const char *fmt, ...)
VSB_vprintf(ctx->msg, fmt, args);
VRT_handling(ctx, VCL_RET_FAIL);
}
else {
AN(ctx->vsl);
else if (ctx->vsl)
VSLbv(ctx->vsl, SLT_VCL_Error, fmt, args);
}
else
/* An error message in vcl_fini() cannot be formatted */
VSL(SLT_VCL_Error, 0, fmt);
va_end(args);
}
......@@ -308,6 +314,10 @@ vmod_decode(VRT_CTX, VCL_ENUM decs, const char *p, ...) {
ssize_t len;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
if (INIT_FINI(ctx)) {
ILLEGAL(ctx, "decode()");
return NULL;
}
snap = WS_Snapshot(ctx->ws);
if ((b = WS_Alloc(ctx->ws, sizeof(struct vmod_priv))) == NULL) {
......@@ -351,6 +361,10 @@ vmod_encode(VRT_CTX, VCL_ENUM encs, VCL_BLOB b) {
ssize_t len;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
if (INIT_FINI(ctx)) {
ILLEGAL(ctx, "encode()");
return NULL;
}
if (b == NULL)
return NULL;
......@@ -383,6 +397,10 @@ vmod_transcode(VRT_CTX, VCL_ENUM decs, VCL_ENUM encs, const char *p, ...) {
va_list ap;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
if (INIT_FINI(ctx)) {
ILLEGAL(ctx, "transcode()");
return NULL;
}
/*
* If the encoding and decoding are the same, just return the
......
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