[master] d3df1f640 vav: Treat a trailing comma as a separator

Dridi Boukelmoune dridi.boukelmoune at gmail.com
Fri Jul 2 17:33:05 UTC 2021


commit d3df1f64014bb7d6a8898a0b9f9d84e3f4dc11fb
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date:   Fri Jul 2 11:36:38 2021 +0200

    vav: Treat a trailing comma as a separator
    
    Let's consider the following VAV strings:
    
        "foo bar baz"
        "foo,bar,baz"
        " foo bar baz "
        " foo,bar,baz "
        "  foo  bar  baz  "
    
    They are all equivalent because consecutive spaces are considered to
    form a single separator. However, consecutive commas aren't:
    
        "foo,bar,baz"
        "foo,,bar,,baz"
    
    In the example above the first string has 3 arguments while the second
    has 5 of them. This behavior was however inconsistent with trailing
    commas:
    
        "foo,bar,baz"
        "foo,bar,baz,"
        "foo,bar,baz,,"
    
    When it comes to trailing commas the first two strings above would
    contain 3 arguments, and the last string would contain 4 arguments.
    
    With this change, they respectively contain 3, 4 and 5 arguments.

diff --git a/lib/libvarnish/vav.c b/lib/libvarnish/vav.c
index a25ed58fc..8679b087c 100644
--- a/lib/libvarnish/vav.c
+++ b/lib/libvarnish/vav.c
@@ -143,11 +143,12 @@ VAV_ParseTxt(const char *b, const char *e, int *argc, int flag)
 	char **argv;
 	const char *p;
 	int nargv, largv;
-	int i, quote;
+	int i, quote, more;
 
 	AN(b);
 	if (e == NULL)
 		e = strchr(b, '\0');
+	more = 0;
 	nargv = 1;
 	largv = 16;
 	argv = calloc(largv, sizeof *argv);
@@ -161,6 +162,7 @@ VAV_ParseTxt(const char *b, const char *e, int *argc, int flag)
 		}
 		if ((flag & ARGV_COMMENT) && *b == '#')
 			break;
+		more = 0;
 		if (*b == '"' && !(flag & ARGV_NOESC)) {
 			p = ++b;
 			quote = 1;
@@ -185,8 +187,10 @@ VAV_ParseTxt(const char *b, const char *e, int *argc, int flag)
 			if (!quote) {
 				if (b >= e || isspace(*b))
 					break;
-				if ((flag & ARGV_COMMA) && *b == ',')
+				if ((flag & ARGV_COMMA) && *b == ',') {
+					more = 1;
 					break;
+				}
 				b++;
 				continue;
 			}
@@ -198,7 +202,8 @@ VAV_ParseTxt(const char *b, const char *e, int *argc, int flag)
 			argv[0] = err_missing_quote;
 			return (argv);
 		}
-		if (nargv + 1 >= largv) {
+		/* Ensure 1 slot for the new argument plus 1 more */
+		if (nargv + 2 >= largv) {
 			argv = realloc(argv, sizeof (*argv) * (largv += largv));
 			assert(argv != NULL);
 		}
@@ -214,6 +219,12 @@ VAV_ParseTxt(const char *b, const char *e, int *argc, int flag)
 		if (b < e)
 			b++;
 	}
+	if (more) {
+		AN(flag & ARGV_COMMA);
+		argv[nargv] = strdup("");
+		assert(argv[nargv] != NULL);
+		nargv++;
+	}
 	argv[nargv] = NULL;
 	if (argc != NULL)
 		*argc = nargv;


More information about the varnish-commit mailing list