[4.1] 298dc44 Make nested includes starting with "./" relative to the including VCL file, and illegal everywhere else.

Lasse Karstensen lkarsten at varnish-software.com
Thu Jan 14 15:15:12 CET 2016


commit 298dc4444ee73189833629214e06dad38b31b208
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Fri Jan 8 22:06:26 2016 +0000

    Make nested includes starting with "./" relative to the including
    VCL file, and illegal everywhere else.
    
    This makes it easier to distribute "VCL-packages"
    
    Test-case written by:	Kacper

diff --git a/bin/varnishtest/tests/v00046.vtc b/bin/varnishtest/tests/v00046.vtc
new file mode 100644
index 0000000..567d3af
--- /dev/null
+++ b/bin/varnishtest/tests/v00046.vtc
@@ -0,0 +1,73 @@
+varnishtest "Test relative to vcl_dir, dot-include and absolute includes"
+
+# relative plain
+shell "true > ${tmpdir}/_start.vcl"
+varnish v1 -arg "-p vcl_dir=${tmpdir}" -vcl {
+	backend b { .host = "127.0.0.1"; }
+	include "_start.vcl" ;
+}
+
+# absolute include
+varnish v1 -vcl {
+	backend b { .host = "127.0.0.1"; }
+	include "${tmpdir}/_start.vcl" ;
+}
+
+# absolute -> relative include
+shell "mkdir -p ${tmpdir}/1/2/3"
+shell "true  > ${tmpdir}/1/2/b.vcl"
+shell "echo 'include \"./2/b.vcl\";' > ${tmpdir}/1/a.vcl"
+varnish v1 -vcl {
+	backend b { .host = "127.0.0.1"; }
+	include "${tmpdir}/1/a.vcl" ;
+}
+
+# same but relative to vcl_dir
+shell "echo 'include \"1/2/b.vcl\";' > ${tmpdir}/1/ab.vcl"
+varnish v1 -vcl {
+	backend b { .host = "127.0.0.1"; }
+	include "1/ab.vcl" ;
+}
+
+# dot-relative -> relative
+varnish v1 -vcl {
+	backend b { .host = "127.0.0.1"; }
+	include "1/a.vcl" ;
+}
+
+# relative -> relative -> relative
+shell "echo 'include \"./3/c.vcl\";' > ${tmpdir}/1/2/b.vcl"
+shell "true  > ${tmpdir}/1/2/3/c.vcl"
+varnish v1 -vcl {
+	backend b { .host = "127.0.0.1"; }
+	include "1/a.vcl" ;
+}
+
+# relative -> absolute
+shell "echo 'include \"${tmpdir}/1/2/3/c.vcl\";' > ${tmpdir}/1/aa.vcl"
+varnish v1 -vcl {
+	backend b { .host = "127.0.0.1"; }
+	include "1/aa.vcl" ;
+}
+
+# relative -> absolute -> relative
+shell "echo 'include \"${tmpdir}/1/2/b.vcl\";' > ${tmpdir}/1/aaa.vcl"
+varnish v1 -vcl {
+	backend b { .host = "127.0.0.1"; }
+	include "1/aaa.vcl" ;
+}
+
+# includes and parses out
+shell "echo 'zool' > ${tmpdir}/1/2/3/c.vcl"
+varnish v1 -errvcl {Found: 'zool' at} {
+	backend b { .host = "127.0.0.1"; }
+	include "1/a.vcl";
+}
+
+shell "rm -f ${tmpdir}/a"
+shell "rm -f ${tmpdir}/_start.vcl"
+
+varnish v1 -errvcl {only works in nested VCL include files} {
+	include "./foobar";
+}
+
diff --git a/lib/libvcc/vcc_compile.c b/lib/libvcc/vcc_compile.c
index 95eab85..8bc60ed 100644
--- a/lib/libvcc/vcc_compile.c
+++ b/lib/libvcc/vcc_compile.c
@@ -478,6 +478,8 @@ vcc_resolve_includes(struct vcc *tl)
 {
 	struct token *t, *t1, *t2;
 	struct source *sp;
+	struct vsb *vsb;
+	const char *p;
 
 	VTAILQ_FOREACH(t, &tl->tokens, list) {
 		if (t->tok != ID || !vcc_IdIs(t, "include"))
@@ -501,7 +503,31 @@ vcc_resolve_includes(struct vcc *tl)
 			return;
 		}
 
-		sp = vcc_file_source(tl->param, tl->sb, t1->dec);
+		if (t1->dec[0] == '.' && t1->dec[1] == '/') {
+			/*
+			 * Nested include filenames, starting with "./" are
+			 * resolved relative to the VCL file which contains
+			 * the include directive.
+			 */
+			if (t1->src->name[0] != '/') {
+				VSB_printf(tl->sb,
+				    "include \"./xxxxx\"; only works in "
+				    "nested VCL include files\n");
+				vcc_ErrWhere(tl, t1);
+				return;
+			}
+			vsb = VSB_new_auto();
+			AN(vsb);
+			p = strrchr(t1->src->name, '/');
+			AN(p);
+			VSB_bcat(vsb, t1->src->name, p - t1->src->name);
+			VSB_cat(vsb, t1->dec + 1);
+			AZ(VSB_finish(vsb));
+			sp = vcc_file_source(tl->param, tl->sb, VSB_data(vsb));
+			VSB_delete(vsb);
+		} else {
+			sp = vcc_file_source(tl->param, tl->sb, t1->dec);
+		}
 		if (sp == NULL) {
 			vcc_ErrWhere(tl, t1);
 			return;
@@ -761,7 +787,7 @@ VCC_Compile(const struct vcp *vcp, struct vsb *sb,
 
 	if (vclsrc != NULL) {
 		AZ(vclsrcfile);
-		sp = vcc_new_source(vclsrc, NULL, "input");
+		sp = vcc_new_source(vclsrc, NULL, "<input>");
 	} else {
 		AN(vclsrcfile);
 		sp = vcc_file_source(vcp, sb, vclsrcfile);



More information about the varnish-commit mailing list