On Fri, 20 Sep 2013, Oliver wrote: > From: Oliver Smith <oliver@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx> > > This reworks the argument parsing functionality of ipset to handle > quote-delimited lines in such a way that they are considered to be a > single argument. > > This commit is necessary for ipset to successfully restore sets that > have comments. > > Signed-off-by: Oliver Smith <oliver@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx> > --- > src/ipset.c | 54 +++++++++++++++++++++++++++++++++++++++++++++--------- > 1 file changed, 45 insertions(+), 9 deletions(-) > > diff --git a/src/ipset.c b/src/ipset.c > index 4f308da..fe73f96 100644 > --- a/src/ipset.c > +++ b/src/ipset.c > @@ -159,25 +159,59 @@ ipset_print_file(const char *fmt, ...) > static void > build_argv(char *buffer) > { > - char *ptr; > + char *tmp, *arg; > int i; > + bool quoted = false; > > /* Reset */ > - for (i = 1; i < newargc; i++) > + for (i = 1; i < newargc; i++) { > + if (newargv[i]) > + free(newargv[i]); > newargv[i] = NULL; > + } > newargc = 1; > > - ptr = strtok(buffer, " \t\r\n"); > - newargv[newargc++] = ptr; > - while ((ptr = strtok(NULL, " \t\r\n")) != NULL) { > - if ((newargc + 1) < (int)(sizeof(newargv)/sizeof(char *))) > - newargv[newargc++] = ptr; > - else { > + arg = calloc(strlen(buffer) + 1, sizeof(*buffer)); > + for (tmp = buffer, i = 0; *tmp; tmp++) { > + if ((newargc + 1) == (int)(sizeof(newargv)/sizeof(char *))) { > exit_error(PARAMETER_PROBLEM, > "Line is too long to parse."); > return; > } > + switch (*tmp) { > + case '\\': > + arg[i++] = *++tmp; > + if (*(tmp+1)) > + continue; > + break; This opens up a can of worms: if escape character is accepted, then that should be put back at printing/saving. Otherwise comments like "This is \"a funny\" comment" will be parsed right, but printed/saved broken. Maybe it's much simpler to emit an error and reject escaping. > + case '"': > + quoted = !quoted; > + if (*(tmp+1)) > + continue; > + break; > + case ' ': > + case '\r': > + case '\n': > + if (!quoted) > + break; > + arg[i++] = *tmp; > + continue; The handling of "\t" is missing. > + default: > + arg[i++] = *tmp; > + if (*(tmp+1)) > + continue; > + break; > + } > + if (!*(tmp+1) && quoted) { > + exit_error(PARAMETER_PROBLEM, "missing close quote"); > + return; > + } > + newargv[newargc] = calloc(strlen(arg) + 1, sizeof(*arg)); > + ipset_strlcpy(newargv[newargc++], arg, strlen(arg) + 1); > + memset(arg, 0, strlen(arg) + 1); > + i = 0; > } > + free(arg); > } > > /* Main parser function, workhorse */ > @@ -195,7 +229,8 @@ restore(char *argv0) > > /* Initialize newargv/newargc */ > newargc = 0; > - newargv[newargc++] = argv0; > + newargv[newargc] = calloc(strlen(argv0) + 1, sizeof(*argv0)); > + ipset_strlcpy(newargv[newargc++], argv0, strlen(argv0) + 1); > if (filename) { > fd = fopen(filename, "r"); > if (!fd) { > @@ -232,6 +267,7 @@ restore(char *argv0) > if (ret < 0) > handle_error(); > > + free(newargv[0]); > return ret; > } > > -- > 1.8.3.2 Best regards, Jozsef - E-mail : kadlec@xxxxxxxxxxxxxxxxx, kadlecsik.jozsef@xxxxxxxxxxxxx PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt Address : Wigner Research Centre for Physics, Hungarian Academy of Sciences H-1525 Budapest 114, POB. 49, Hungary -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html