[7.0] f5798fd1f vcc: do not overwrite SUB symbol properties when call'ing

Nils Goroll nils.goroll at uplex.de
Mon Nov 8 15:11:07 UTC 2021


commit f5798fd1f9362e2a56933c457ead9b85e9d97c79
Author: Nils Goroll <nils.goroll at uplex.de>
Date:   Mon Oct 25 18:46:14 2021 +0200

    vcc: do not overwrite SUB symbol properties when call'ing
    
    vcc_act_call() implements use-before-define semantics. To do so, it
    needs to instantiate SUB symbols if they do not exist.
    
    However, it wrongly called VCC_GlobalSymbol() also for existing
    symbols, overwriting symbol properties.
    
    In the case of the built-in subs, the symbol's lname (historically)
    still is the unescaped literal name, while user defined subs have
    their name escaped via VCC_GlobalSymbol() -> VCC_PrintCName().
    
    This made the wrong call to VCC_GlobalSymbol() apparent when a
    built-in sub was called with an explicit "call" action.
    
    Besides fixing the VCC_GlobalSymbol() call, we also need to set the
    lname and rname attributes for built-in SUB symbols initialized in
    VCC_New().
    
    Alternatively, we could also have used VCC_GlobalSymbol() there, but
    that would have affected other places where we (still) rely on the
    known name scheme of built-in subs, e.h. EmitStruct(). While the name
    unifaction was nice in general, I found the necessary changes (look up
    SUB symbols) not worth the benefit.
    
    Fixes #3719

diff --git a/bin/varnishtest/tests/m00053.vtc b/bin/varnishtest/tests/m00053.vtc
index d5c501ea4..97ed034ce 100644
--- a/bin/varnishtest/tests/m00053.vtc
+++ b/bin/varnishtest/tests/m00053.vtc
@@ -92,9 +92,12 @@ varnish v1 -vcl {
 	sub vcl_backend_fetch {
 		debug.call(priv_top);
 	}
+	sub vcl_backend_response {
+		set beresp.status = 200;
+	}
 	sub vcl_backend_error {
 		# falling through to None backend would be success
-		set beresp.status = 200;
+		call vcl_backend_response;
 		return (deliver);
 	}
 } -start
diff --git a/lib/libvcc/vcc_action.c b/lib/libvcc/vcc_action.c
index 7c7a57714..0ed675da6 100644
--- a/lib/libvcc/vcc_action.c
+++ b/lib/libvcc/vcc_action.c
@@ -52,16 +52,16 @@ vcc_act_call(struct vcc *tl, struct token *t, struct symbol *sym)
 	t0 = tl->t;
 	sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE, SYMTAB_PARTIAL_NOERR,
 	    XREF_REF);
-	if (sym == NULL)
+	if (sym == NULL) {
 		sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_SUB, SYMTAB_CREATE,
 		    XREF_REF);
-
-	if (sym == NULL)
-		return;
+		if (sym == NULL)
+			return;
+		VCC_GlobalSymbol(sym, SUB);
+	}
 
 	if (sym->kind == SYM_SUB) {
 		vcc_AddCall(tl, t0, sym);
-		VCC_GlobalSymbol(sym, SUB);
 
 		Fb(tl, 1, "%s(ctx, VSUB_STATIC, NULL);\n", sym->lname);
 		SkipToken(tl, ';');
diff --git a/lib/libvcc/vcc_compile.c b/lib/libvcc/vcc_compile.c
index 60427d526..d954ea8b9 100644
--- a/lib/libvcc/vcc_compile.c
+++ b/lib/libvcc/vcc_compile.c
@@ -820,6 +820,7 @@ VCC_New(void)
 	struct vcc *tl;
 	struct symbol *sym;
 	struct proc *p;
+	struct vsb *vsb;
 	int i;
 
 	ALLOC_OBJ(tl, VCC_MAGIC);
@@ -849,7 +850,25 @@ VCC_New(void)
 		    SYM_MAIN, SYM_SUB, VCL_LOW, VCL_HIGH);
 		p = vcc_NewProc(tl, sym);
 		p->method = &method_tab[i];
-		VSB_printf(p->cname, "VGC_function_%s", p->method->name);
+
+		// see also VCC_GlobalSymbol()
+		vsb = VSB_new_auto();
+		AN(vsb);
+		VSB_printf(vsb, "%s_%s", SUB->global_pfx, p->method->name);
+		AZ(VSB_finish(vsb));
+
+		AZ(VSB_bcat(p->cname, VSB_data(vsb), VSB_len(vsb)));
+
+		sym->lname = strdup(VSB_data(vsb));
+		AN(sym->lname);
+
+		VSB_clear(vsb);
+		VSB_printf(vsb, "sub_%s", sym->lname);
+		AZ(VSB_finish(vsb));
+
+		sym->rname = strdup(VSB_data(vsb));
+		AN(sym->rname);
+		VSB_destroy(&vsb);
 	}
 	tl->sb = VSB_new_auto();
 	AN(tl->sb);


More information about the varnish-commit mailing list