[master] ed278561f Refactor the recursive include check.

Poul-Henning Kamp phk at FreeBSD.org
Fri May 7 08:56:06 UTC 2021


commit ed278561f1e4c77d3968814e9ece9015b148d3cc
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Fri May 7 08:53:51 2021 +0000

    Refactor the recursive include check.

diff --git a/bin/varnishtest/tests/r03360.vtc b/bin/varnishtest/tests/r03360.vtc
index 337ce7c69..94f9fd21c 100644
--- a/bin/varnishtest/tests/r03360.vtc
+++ b/bin/varnishtest/tests/r03360.vtc
@@ -4,12 +4,12 @@ shell {echo include '"_recurse.vcl";' > ${tmpdir}/_recurse.vcl}
 shell {echo include +glob '"${tmpdir}/_recurse[2].vcl";' > ${tmpdir}/_recurse1.vcl}
 shell {echo include '"_recurse1.vcl";' > ${tmpdir}/_recurse2.vcl}
 
-varnish v1 -arg "-p vcl_path=${tmpdir}" -errvcl "Recursive include of" {
+varnish v1 -arg "-p vcl_path=${tmpdir}" -errvcl "Recursive use of file" {
 	backend b { .host = "${localhost}"; }
 	include "_recurse.vcl" ;
 }
 
-varnish v2 -arg "-p vcl_path=${tmpdir}" -errvcl "Recursive include of" {
+varnish v2 -arg "-p vcl_path=${tmpdir}" -errvcl "Recursive use of file" {
 	backend b { .host = "${localhost}"; }
 	include "_recurse1.vcl" ;
 }
diff --git a/lib/libvcc/vcc_compile.c b/lib/libvcc/vcc_compile.c
index a82fc9760..d270b0ef1 100644
--- a/lib/libvcc/vcc_compile.c
+++ b/lib/libvcc/vcc_compile.c
@@ -642,7 +642,7 @@ vcc_CompileSource(struct vcc *tl, struct source *sp, const char *jfile)
 	}
 
 	/* Register and lex the builtin VCL */
-	sp = vcc_new_source(tl->builtin_vcl, "Builtin");
+	sp = vcc_new_source(tl->builtin_vcl, "builtin", "<builtin>");
 	assert(sp != NULL);
 	vcc_lex_source(tl, sp, 1);
 	if (tl->err)
@@ -790,7 +790,7 @@ VCC_Compile(struct vcc *tl, struct vsb **sb,
 	}
 
 	if (vclsrc != NULL)
-		sp = vcc_new_source(vclsrc, vclsrcfile);
+		sp = vcc_new_source(vclsrc, "vcl.inline", vclsrcfile);
 	else
 		sp = vcc_file_source(tl, vclsrcfile);
 
diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h
index 2219531d1..58308d951 100644
--- a/lib/libvcc/vcc_compile.h
+++ b/lib/libvcc/vcc_compile.h
@@ -79,12 +79,14 @@ void vcl_output_lang_h(struct vsb *sb);
 #define INDENT		2
 
 struct source {
+	unsigned		magic;
+#define SOURCE_MAGIC		0xf756fe82
 	VTAILQ_ENTRY(source)	list;
+	const char		*kind;
 	char			*name;
 	const char		*b;
 	const char		*e;
 	unsigned		idx;
-	char			*freeit;
 	const struct source	*parent;
 	const struct token	*parent_tok;
 	VTAILQ_HEAD(, token)	src_tokens;
@@ -364,8 +366,9 @@ void vcc_Parse_Init(struct vcc *);
 sym_act_f vcc_Act_If;
 
 /* vcc_source.c */
-struct source * vcc_new_source(const char *src, const char *name);
-struct source *vcc_file_source(const struct vcc *tl, const char *fn);
+struct source * vcc_new_source(const char *src, const char *kind,
+    const char *name);
+struct source *vcc_file_source(struct vcc *tl, const char *fn);
 void vcc_lex_source(struct vcc *tl, struct source *sp, int eoi);
 
 /* vcc_storage.c */
diff --git a/lib/libvcc/vcc_source.c b/lib/libvcc/vcc_source.c
index db953d2be..57167b37e 100644
--- a/lib/libvcc/vcc_source.c
+++ b/lib/libvcc/vcc_source.c
@@ -41,15 +41,16 @@
 #include "vfil.h"
 
 struct source *
-vcc_new_source(const char *src, const char *name)
+vcc_new_source(const char *src, const char *kind, const char *name)
 {
 	struct source *sp;
 
 	AN(src);
 	AN(name);
-	sp = calloc(1, sizeof *sp);
+	ALLOC_OBJ(sp, SOURCE_MAGIC);
 	AN(sp);
 	REPLACE(sp->name, name);
+	sp->kind = kind;
 	sp->b = src;
 	sp->e = strchr(src, '\0');
 	VTAILQ_INIT(&sp->src_tokens);
@@ -58,31 +59,15 @@ vcc_new_source(const char *src, const char *name)
 
 /*--------------------------------------------------------------------*/
 
-static void
-vcc_destroy_source(struct source **spp)
-{
-	struct source *sp;
-
-	AN(spp);
-	sp = *spp;
-	*spp = NULL;
-
-	AN(sp);
-	free(sp->name);
-	free(sp->freeit);
-	free(sp);
-}
-
-/*--------------------------------------------------------------------*/
-
 struct source *
-vcc_file_source(const struct vcc *tl, const char *fn)
+vcc_file_source(struct vcc *tl, const char *fn)
 {
 	char *f, *fnp;
 	struct source *sp;
 
 	if (!tl->unsafe_path && strchr(fn, '/') != NULL) {
 		VSB_printf(tl->sb, "VCL filename '%s' is unsafe.\n", fn);
+		tl->err = 1;
 		return (NULL);
 	}
 	f = NULL;
@@ -90,70 +75,60 @@ vcc_file_source(const struct vcc *tl, const char *fn)
 		VSB_printf(tl->sb, "Cannot read file '%s' (%s)\n",
 		    fnp != NULL ? fnp : fn, strerror(errno));
 		free(fnp);
+		tl->err = 1;
 		return (NULL);
 	}
-	sp = vcc_new_source(f, fnp);
+	sp = vcc_new_source(f, "file", fnp);
 	free(fnp);
-	sp->freeit = f;
 	return (sp);
 }
 
 /*--------------------------------------------------------------------*/
 
-static int
+static void
 vcc_include_file(struct vcc *tl, const struct source *src_sp,
     const char *filename, const struct token *parent_token)
 {
 	struct source *sp;
-	const struct source *sp1;
 
 	sp = vcc_file_source(tl, filename);
 	if (sp == NULL)
-		return (-1);
+		return;
 
-	for (sp1 = src_sp; sp1 != NULL; sp1 = sp1->parent)
-		if (!strcmp(sp1->name, sp->name))
-			break;
-	if (sp1 != NULL) {
-		VSB_printf(tl->sb,
-		    "Recursive include of \"%s\"\n\n", sp->name);
-		vcc_destroy_source(&sp);
-		return (-1);
-	}
 	sp->parent = src_sp;
 	sp->parent_tok = parent_token;
 	vcc_lex_source(tl, sp, 0);
-	return (0);
 }
 
 /*--------------------------------------------------------------------*/
 
-static int
+static void
 vcc_include_glob_file(struct vcc *tl, const struct source *src_sp,
     const char *filename, const struct token *parent_token)
 {
 	glob_t	g[1];
-	int rv;
 	unsigned u;
+	int i;
 
 	memset(g, 0, sizeof g);
-	rv = glob(filename, 0, NULL, g);
-	switch (rv) {
+	i = glob(filename, 0, NULL, g);
+	switch (i) {
 	case 0:
-		for (u = 0; rv == 0 && u < g->gl_pathc; u++) {
-			rv = vcc_include_file(
+		for (u = 0; !tl->err && u < g->gl_pathc; u++) {
+			vcc_include_file(
 			    tl, src_sp, g->gl_pathv[u], parent_token);
 		}
 		break;
 	case GLOB_NOMATCH:
 		VSB_printf(tl->sb, "glob pattern matched no files.\n");
+		tl->err = 1;
 		break;
 	default:
-		VSB_printf(tl->sb, "glob(3) expansion failed (%d)\n", rv);
+		VSB_printf(tl->sb, "glob(3) expansion failed (%d)\n", i);
+		tl->err = 1;
 		break;
 	}
 	globfree(g);
-	return (rv);
 }
 
 /*--------------------------------------------------------------------
@@ -166,7 +141,6 @@ vcc_lex_include(struct vcc *tl, const struct source *src_sp, struct token *t)
 {
 	struct token *tok1;
 	int i, glob_flag = 0;
-	const struct source *sp1;
 	struct vsb *vsb = NULL;
 	const char *filename;
 	const char *p;
@@ -235,19 +209,13 @@ vcc_lex_include(struct vcc *tl, const struct source *src_sp, struct token *t)
 	}
 
 	if (glob_flag)
-		i = vcc_include_glob_file(tl, src_sp, filename, tok1);
+		vcc_include_glob_file(tl, src_sp, filename, tok1);
 	else
-		i = vcc_include_file(tl, src_sp, filename, tok1);
+		vcc_include_file(tl, src_sp, filename, tok1);
 	if (vsb != NULL)
 		VSB_destroy(&vsb);
-	if (i) {
+	if (tl->err)
 		vcc_ErrWhere(tl, tok1);
-		for (sp1 = src_sp; sp1 != NULL; sp1 = sp1->parent) {
-			if (sp1->parent_tok == NULL)
-				break;
-			vcc_ErrWhere(tl, sp1->parent_tok);
-		}
-	}
 	return (t);
 }
 
@@ -255,6 +223,20 @@ void
 vcc_lex_source(struct vcc *tl, struct source *src_sp, int eoi)
 {
 	struct token *t;
+	const struct source *sp1;
+
+	CHECK_OBJ_NOTNULL(src_sp, SOURCE_MAGIC);
+
+	for (sp1 = src_sp->parent; sp1 != NULL; sp1 = sp1->parent) {
+		if (!strcmp(sp1->name, src_sp->name) &&
+		    !strcmp(sp1->kind, src_sp->kind)) {
+			VSB_printf(tl->sb,
+			    "Recursive use of %s \"%s\"\n\n",
+			    src_sp->kind, src_sp->name);
+			tl->err = 1;
+			return;
+		}
+	}
 
 	VTAILQ_INSERT_TAIL(&tl->sources, src_sp, list);
 	src_sp->idx = tl->nsources++;


More information about the varnish-commit mailing list