[master] 3c68fa77e Fix callling a dynamic sub for object methods
Nils Goroll
nils.goroll at uplex.de
Wed Feb 17 19:20:03 UTC 2021
commit 3c68fa77ecc5ed1b254abde8b692f2793dc0ea5e
Author: Nils Goroll <nils.goroll at uplex.de>
Date: Tue Feb 16 17:52:52 2021 +0100
Fix callling a dynamic sub for object methods
7ec28f1ae91bd39e6e89beb7dffd4248c5054414 did not work with object
methods because we need a partial symbol table lookup to identify them,
otherwise the symbol kind we find is just SUB for the method's return
value.
Additions to the test case and vmod_debug by @slimhazard, thank you
Fixes #3521
diff --git a/bin/varnishtest/tests/m00053.vtc b/bin/varnishtest/tests/m00053.vtc
index 68034edbc..d5c501ea4 100644
--- a/bin/varnishtest/tests/m00053.vtc
+++ b/bin/varnishtest/tests/m00053.vtc
@@ -192,3 +192,46 @@ logexpect l3 -wait
client c4 -wait
client c5 -wait
client c6 -wait
+
+varnish v1 -vcl {
+ import debug;
+ backend b None;
+
+ sub foo {
+ set resp.http.Foo = "Called";
+ }
+
+ sub vcl_init {
+ new c = debug.caller(foo);
+ }
+
+ sub vcl_recv {
+ return (synth(200));
+ }
+
+ sub vcl_synth {
+ if (req.url == "/call") {
+ call c.xsub();
+ } else {
+ c.call();
+ }
+ return (deliver);
+ }
+}
+
+client c1 {
+ txreq -url "/call"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.Foo == "Called"
+} -start
+
+client c2 {
+ txreq
+ rxresp
+ expect resp.status == 200
+ expect resp.http.Foo == "Called"
+} -start
+
+client c1 -wait
+client c2 -wait
diff --git a/lib/libvcc/vcc_action.c b/lib/libvcc/vcc_action.c
index 71c9b91db..57a2f6daf 100644
--- a/lib/libvcc/vcc_action.c
+++ b/lib/libvcc/vcc_action.c
@@ -50,8 +50,8 @@ vcc_act_call(struct vcc *tl, struct token *t, struct symbol *sym)
(void)t;
ExpectErr(tl, ID);
t0 = tl->t;
- sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE, SYMTAB_NOERR, XREF_REF);
-
+ sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE, SYMTAB_PARTIAL_NOERR,
+ XREF_REF);
if (sym == NULL)
sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_SUB, SYMTAB_CREATE,
XREF_REF);
diff --git a/vmod/vmod_debug.c b/vmod/vmod_debug.c
index 25ce2f76e..8f123c276 100644
--- a/vmod/vmod_debug.c
+++ b/vmod/vmod_debug.c
@@ -1331,3 +1331,62 @@ xyzzy_total_recall(VRT_CTX)
return (wrong);
}
+
+/*---------------------------------------------------------------------*/
+
+struct VPFX(debug_caller) {
+ unsigned magic;
+#define DEBUG_CALLER_MAGIC 0xb47f3449
+ VCL_SUB sub;
+};
+
+VCL_VOID v_matchproto_(td_xyzzy_debug_caller__init)
+xyzzy_caller__init(VRT_CTX, struct VPFX(debug_caller) **callerp,
+ const char *name, VCL_SUB sub)
+{
+ struct VPFX(debug_caller) *caller;
+
+ CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+ AN(callerp);
+ AZ(*callerp);
+ AN(name);
+ AN(sub);
+
+ ALLOC_OBJ(caller, DEBUG_CALLER_MAGIC);
+ AN(caller);
+ *callerp = caller;
+ caller->sub = sub;
+}
+
+VCL_VOID v_matchproto_(td_xyzzy_debug_caller__fini)
+xyzzy_caller__fini(struct VPFX(debug_caller) **callerp)
+{
+ struct VPFX(debug_caller) *caller;
+
+ if (callerp == NULL || *callerp == NULL)
+ return;
+ CHECK_OBJ(*callerp, DEBUG_CALLER_MAGIC);
+ caller = *callerp;
+ *callerp = NULL;
+ FREE_OBJ(caller);
+}
+
+VCL_VOID v_matchproto_(td_xyzzy_debug_caller_call)
+xyzzy_caller_call(VRT_CTX, struct VPFX(debug_caller) *caller)
+{
+ CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+ CHECK_OBJ_NOTNULL(caller, DEBUG_CALLER_MAGIC);
+ AN(caller->sub);
+
+ VRT_call(ctx, caller->sub);
+}
+
+VCL_SUB v_matchproto_(td_xyzzy_debug_caller_sub)
+xyzzy_caller_xsub(VRT_CTX, struct VPFX(debug_caller) *caller)
+{
+ CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+ CHECK_OBJ_NOTNULL(caller, DEBUG_CALLER_MAGIC);
+ AN(caller->sub);
+
+ return (caller->sub);
+}
diff --git a/vmod/vmod_debug.vcc b/vmod/vmod_debug.vcc
index 45fc1fdee..c15079630 100644
--- a/vmod/vmod_debug.vcc
+++ b/vmod/vmod_debug.vcc
@@ -340,3 +340,9 @@ To test *WRONG* behavior
$Function SUB total_recall()
To test *WRONG* behavior
+
+$Object caller(SUB)
+
+$Method VOID .call()
+
+$Method SUB .xsub()
More information about the varnish-commit
mailing list