Blame SOURCES/xshared-Consolidate-argv-construction-routines.patch

9a3fa7
From fc87d26b0343a5fbe661acc967f7a7c316531ca5 Mon Sep 17 00:00:00 2001
9a3fa7
From: Phil Sutter <psutter@redhat.com>
9a3fa7
Date: Wed, 3 Apr 2019 20:16:49 +0200
9a3fa7
Subject: [PATCH] xshared: Consolidate argv construction routines
9a3fa7
9a3fa7
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1668475
9a3fa7
Upstream Status: iptables commit a2ed880a19d08
9a3fa7
Conflicts:
9a3fa7
* Context change due to missing commit 2963a8df2175b
9a3fa7
  ("iptables: Remove explicit static variables initalization.").
9a3fa7
* Context change due to missing commit 1cc09188079a6
9a3fa7
  ("xshared: Consolidate parse_counters()").
9a3fa7
* Context change due to previously backported commit 8da04ffdca193
9a3fa7
  ("Share print_ipv{4,6}_addr() from xtables").
9a3fa7
* Dropped changes to non-existing file iptables/xtables-restore.c.
9a3fa7
9a3fa7
commit a2ed880a19d0861342b3515721804b18d698bf44
9a3fa7
Author: Phil Sutter <phil@nwl.cc>
9a3fa7
Date:   Thu Aug 2 17:05:17 2018 +0200
9a3fa7
9a3fa7
    xshared: Consolidate argv construction routines
9a3fa7
9a3fa7
    Implementations were equal in {ip,ip6,x}tables-restore.c. The one in
9a3fa7
    iptables-xml.c differed slightly. For now, collect all features
9a3fa7
    together. Maybe it would make sense to migrate iptables-xml.c to using
9a3fa7
    add_param_to_argv() at some point and therefore extend the latter to
9a3fa7
    store whether a given parameter was quoted or not.
9a3fa7
9a3fa7
    While being at it, a few improvements were done:
9a3fa7
9a3fa7
    * free_argv() now also resets 'newargc' variable, so users don't have to
9a3fa7
      do that anymore.
9a3fa7
    * Indenting level in add_param_to_argv() was reduced a bit.
9a3fa7
    * That long error message is put into a single line to aid in grepping
9a3fa7
      for it.
9a3fa7
    * Explicit call to exit() after xtables_error() is removed since the
9a3fa7
      latter does not return anyway.
9a3fa7
9a3fa7
    Signed-off-by: Phil Sutter <phil@nwl.cc>
9a3fa7
    Signed-off-by: Florian Westphal <fw@strlen.de>
9a3fa7
9a3fa7
Signed-off-by: Phil Sutter <psutter@redhat.com>
9a3fa7
---
9a3fa7
 iptables/ip6tables-restore.c | 107 ++----------------------------
9a3fa7
 iptables/iptables-restore.c  | 107 ++----------------------------
9a3fa7
 iptables/iptables-xml.c      |  63 ------------------
9a3fa7
 iptables/xshared.c           | 123 +++++++++++++++++++++++++++++++++++
9a3fa7
 iptables/xshared.h           |  13 ++++
9a3fa7
 5 files changed, 150 insertions(+), 263 deletions(-)
9a3fa7
9a3fa7
diff --git a/iptables/ip6tables-restore.c b/iptables/ip6tables-restore.c
9a3fa7
index 611430d930eda..1f8cb43286f03 100644
9a3fa7
--- a/iptables/ip6tables-restore.c
9a3fa7
+++ b/iptables/ip6tables-restore.c
9a3fa7
@@ -91,96 +91,6 @@ static int parse_counters(char *string, struct xt_counters *ctr)
9a3fa7
 	return ret == 2;
9a3fa7
 }
9a3fa7
 
9a3fa7
-/* global new argv and argc */
9a3fa7
-static char *newargv[255];
9a3fa7
-static int newargc;
9a3fa7
-
9a3fa7
-/* function adding one argument to newargv, updating newargc
9a3fa7
- * returns true if argument added, false otherwise */
9a3fa7
-static int add_argv(char *what) {
9a3fa7
-	DEBUGP("add_argv: %s\n", what);
9a3fa7
-	if (what && newargc + 1 < ARRAY_SIZE(newargv)) {
9a3fa7
-		newargv[newargc] = strdup(what);
9a3fa7
-		newargv[++newargc] = NULL;
9a3fa7
-		return 1;
9a3fa7
-	} else {
9a3fa7
-		xtables_error(PARAMETER_PROBLEM,
9a3fa7
-			"Parser cannot handle more arguments\n");
9a3fa7
-		return 0;
9a3fa7
-	}
9a3fa7
-}
9a3fa7
-
9a3fa7
-static void free_argv(void) {
9a3fa7
-	int i;
9a3fa7
-
9a3fa7
-	for (i = 0; i < newargc; i++)
9a3fa7
-		free(newargv[i]);
9a3fa7
-}
9a3fa7
-
9a3fa7
-static void add_param_to_argv(char *parsestart)
9a3fa7
-{
9a3fa7
-	int quote_open = 0, escaped = 0, param_len = 0;
9a3fa7
-	char param_buffer[1024], *curchar;
9a3fa7
-
9a3fa7
-	/* After fighting with strtok enough, here's now
9a3fa7
-	 * a 'real' parser. According to Rusty I'm now no
9a3fa7
-	 * longer a real hacker, but I can live with that */
9a3fa7
-
9a3fa7
-	for (curchar = parsestart; *curchar; curchar++) {
9a3fa7
-		if (quote_open) {
9a3fa7
-			if (escaped) {
9a3fa7
-				param_buffer[param_len++] = *curchar;
9a3fa7
-				escaped = 0;
9a3fa7
-				continue;
9a3fa7
-			} else if (*curchar == '\\') {
9a3fa7
-				escaped = 1;
9a3fa7
-				continue;
9a3fa7
-			} else if (*curchar == '"') {
9a3fa7
-				quote_open = 0;
9a3fa7
-				*curchar = ' ';
9a3fa7
-			} else {
9a3fa7
-				param_buffer[param_len++] = *curchar;
9a3fa7
-				continue;
9a3fa7
-			}
9a3fa7
-		} else {
9a3fa7
-			if (*curchar == '"') {
9a3fa7
-				quote_open = 1;
9a3fa7
-				continue;
9a3fa7
-			}
9a3fa7
-		}
9a3fa7
-
9a3fa7
-		if (*curchar == ' '
9a3fa7
-		    || *curchar == '\t'
9a3fa7
-		    || * curchar == '\n') {
9a3fa7
-			if (!param_len) {
9a3fa7
-				/* two spaces? */
9a3fa7
-				continue;
9a3fa7
-			}
9a3fa7
-
9a3fa7
-			param_buffer[param_len] = '\0';
9a3fa7
-
9a3fa7
-			/* check if table name specified */
9a3fa7
-			if (!strncmp(param_buffer, "-t", 2)
9a3fa7
-                            || !strncmp(param_buffer, "--table", 8)) {
9a3fa7
-				xtables_error(PARAMETER_PROBLEM,
9a3fa7
-				"The -t option (seen in line %u) cannot be "
9a3fa7
-				"used in ip6tables-restore.\n", line);
9a3fa7
-				exit(1);
9a3fa7
-			}
9a3fa7
-
9a3fa7
-			add_argv(param_buffer);
9a3fa7
-			param_len = 0;
9a3fa7
-		} else {
9a3fa7
-			/* regular character, copy to buffer */
9a3fa7
-			param_buffer[param_len++] = *curchar;
9a3fa7
-
9a3fa7
-			if (param_len >= sizeof(param_buffer))
9a3fa7
-				xtables_error(PARAMETER_PROBLEM,
9a3fa7
-				   "Parameter too long!");
9a3fa7
-		}
9a3fa7
-	}
9a3fa7
-}
9a3fa7
-
9a3fa7
 int ip6tables_restore_main(int argc, char *argv[])
9a3fa7
 {
9a3fa7
 	struct xtc_handle *handle = NULL;
9a3fa7
@@ -425,9 +335,6 @@ int ip6tables_restore_main(int argc, char *argv[])
9a3fa7
 			char *bcnt = NULL;
9a3fa7
 			char *parsestart;
9a3fa7
 
9a3fa7
-			/* reset the newargv */
9a3fa7
-			newargc = 0;
9a3fa7
-
9a3fa7
 			if (buffer[0] == '[') {
9a3fa7
 				/* we have counters in our input */
9a3fa7
 				char *ptr = strchr(buffer, ']');
9a3fa7
@@ -456,17 +363,17 @@ int ip6tables_restore_main(int argc, char *argv[])
9a3fa7
 				parsestart = buffer;
9a3fa7
 			}
9a3fa7
 
9a3fa7
-			add_argv(argv[0]);
9a3fa7
-			add_argv("-t");
9a3fa7
-			add_argv(curtable);
9a3fa7
+			add_argv(argv[0], 0);
9a3fa7
+			add_argv("-t", 0);
9a3fa7
+			add_argv(curtable, 0);
9a3fa7
 
9a3fa7
 			if (counters && pcnt && bcnt) {
9a3fa7
-				add_argv("--set-counters");
9a3fa7
-				add_argv((char *) pcnt);
9a3fa7
-				add_argv((char *) bcnt);
9a3fa7
+				add_argv("--set-counters", 0);
9a3fa7
+				add_argv((char *) pcnt, 0);
9a3fa7
+				add_argv((char *) bcnt, 0);
9a3fa7
 			}
9a3fa7
 
9a3fa7
-			add_param_to_argv(parsestart);
9a3fa7
+			add_param_to_argv(parsestart, line);
9a3fa7
 
9a3fa7
 			DEBUGP("calling do_command6(%u, argv, &%s, handle):\n",
9a3fa7
 				newargc, curtable);
9a3fa7
diff --git a/iptables/iptables-restore.c b/iptables/iptables-restore.c
9a3fa7
index b0da96d45d297..615e38a6625e0 100644
9a3fa7
--- a/iptables/iptables-restore.c
9a3fa7
+++ b/iptables/iptables-restore.c
9a3fa7
@@ -89,96 +89,6 @@ static int parse_counters(char *string, struct xt_counters *ctr)
9a3fa7
 	return ret == 2;
9a3fa7
 }
9a3fa7
 
9a3fa7
-/* global new argv and argc */
9a3fa7
-static char *newargv[255];
9a3fa7
-static int newargc;
9a3fa7
-
9a3fa7
-/* function adding one argument to newargv, updating newargc 
9a3fa7
- * returns true if argument added, false otherwise */
9a3fa7
-static int add_argv(char *what) {
9a3fa7
-	DEBUGP("add_argv: %s\n", what);
9a3fa7
-	if (what && newargc + 1 < ARRAY_SIZE(newargv)) {
9a3fa7
-		newargv[newargc] = strdup(what);
9a3fa7
-		newargv[++newargc] = NULL;
9a3fa7
-		return 1;
9a3fa7
-	} else {
9a3fa7
-		xtables_error(PARAMETER_PROBLEM,
9a3fa7
-			"Parser cannot handle more arguments\n");
9a3fa7
-		return 0;
9a3fa7
-	}
9a3fa7
-}
9a3fa7
-
9a3fa7
-static void free_argv(void) {
9a3fa7
-	int i;
9a3fa7
-
9a3fa7
-	for (i = 0; i < newargc; i++)
9a3fa7
-		free(newargv[i]);
9a3fa7
-}
9a3fa7
-
9a3fa7
-static void add_param_to_argv(char *parsestart)
9a3fa7
-{
9a3fa7
-	int quote_open = 0, escaped = 0, param_len = 0;
9a3fa7
-	char param_buffer[1024], *curchar;
9a3fa7
-
9a3fa7
-	/* After fighting with strtok enough, here's now
9a3fa7
-	 * a 'real' parser. According to Rusty I'm now no
9a3fa7
-	 * longer a real hacker, but I can live with that */
9a3fa7
-
9a3fa7
-	for (curchar = parsestart; *curchar; curchar++) {
9a3fa7
-		if (quote_open) {
9a3fa7
-			if (escaped) {
9a3fa7
-				param_buffer[param_len++] = *curchar;
9a3fa7
-				escaped = 0;
9a3fa7
-				continue;
9a3fa7
-			} else if (*curchar == '\\') {
9a3fa7
-				escaped = 1;
9a3fa7
-				continue;
9a3fa7
-			} else if (*curchar == '"') {
9a3fa7
-				quote_open = 0;
9a3fa7
-				*curchar = ' ';
9a3fa7
-			} else {
9a3fa7
-				param_buffer[param_len++] = *curchar;
9a3fa7
-				continue;
9a3fa7
-			}
9a3fa7
-		} else {
9a3fa7
-			if (*curchar == '"') {
9a3fa7
-				quote_open = 1;
9a3fa7
-				continue;
9a3fa7
-			}
9a3fa7
-		}
9a3fa7
-
9a3fa7
-		if (*curchar == ' '
9a3fa7
-		    || *curchar == '\t'
9a3fa7
-		    || * curchar == '\n') {
9a3fa7
-			if (!param_len) {
9a3fa7
-				/* two spaces? */
9a3fa7
-				continue;
9a3fa7
-			}
9a3fa7
-
9a3fa7
-			param_buffer[param_len] = '\0';
9a3fa7
-
9a3fa7
-			/* check if table name specified */
9a3fa7
-			if (!strncmp(param_buffer, "-t", 2)
9a3fa7
-			    || !strncmp(param_buffer, "--table", 8)) {
9a3fa7
-				xtables_error(PARAMETER_PROBLEM,
9a3fa7
-				"The -t option (seen in line %u) cannot be "
9a3fa7
-				"used in iptables-restore.\n", line);
9a3fa7
-				exit(1);
9a3fa7
-			}
9a3fa7
-
9a3fa7
-			add_argv(param_buffer);
9a3fa7
-			param_len = 0;
9a3fa7
-		} else {
9a3fa7
-			/* regular character, copy to buffer */
9a3fa7
-			param_buffer[param_len++] = *curchar;
9a3fa7
-
9a3fa7
-			if (param_len >= sizeof(param_buffer))
9a3fa7
-				xtables_error(PARAMETER_PROBLEM,
9a3fa7
-				   "Parameter too long!");
9a3fa7
-		}
9a3fa7
-	}
9a3fa7
-}
9a3fa7
-
9a3fa7
 int
9a3fa7
 iptables_restore_main(int argc, char *argv[])
9a3fa7
 {
9a3fa7
@@ -424,9 +334,6 @@ iptables_restore_main(int argc, char *argv[])
9a3fa7
 			char *bcnt = NULL;
9a3fa7
 			char *parsestart;
9a3fa7
 
9a3fa7
-			/* reset the newargv */
9a3fa7
-			newargc = 0;
9a3fa7
-
9a3fa7
 			if (buffer[0] == '[') {
9a3fa7
 				/* we have counters in our input */
9a3fa7
 				char *ptr = strchr(buffer, ']');
9a3fa7
@@ -455,17 +362,17 @@ iptables_restore_main(int argc, char *argv[])
9a3fa7
 				parsestart = buffer;
9a3fa7
 			}
9a3fa7
 
9a3fa7
-			add_argv(argv[0]);
9a3fa7
-			add_argv("-t");
9a3fa7
-			add_argv(curtable);
9a3fa7
+			add_argv(argv[0], 0);
9a3fa7
+			add_argv("-t", 0);
9a3fa7
+			add_argv(curtable, 0);
9a3fa7
 
9a3fa7
 			if (counters && pcnt && bcnt) {
9a3fa7
-				add_argv("--set-counters");
9a3fa7
-				add_argv((char *) pcnt);
9a3fa7
-				add_argv((char *) bcnt);
9a3fa7
+				add_argv("--set-counters", 0);
9a3fa7
+				add_argv((char *) pcnt, 0);
9a3fa7
+				add_argv((char *) bcnt, 0);
9a3fa7
 			}
9a3fa7
 
9a3fa7
-			add_param_to_argv(parsestart);
9a3fa7
+			add_param_to_argv(parsestart, line);
9a3fa7
 
9a3fa7
 			DEBUGP("calling do_command4(%u, argv, &%s, handle):\n",
9a3fa7
 				newargc, curtable);
9a3fa7
diff --git a/iptables/iptables-xml.c b/iptables/iptables-xml.c
9a3fa7
index c523a132b2240..49f8ea2826181 100644
9a3fa7
--- a/iptables/iptables-xml.c
9a3fa7
+++ b/iptables/iptables-xml.c
9a3fa7
@@ -66,16 +66,6 @@ parse_counters(char *string, struct xt_counters *ctr)
9a3fa7
 		return (0 == 2);
9a3fa7
 }
9a3fa7
 
9a3fa7
-/* global new argv and argc */
9a3fa7
-static char *newargv[255];
9a3fa7
-static unsigned int newargc = 0;
9a3fa7
-
9a3fa7
-static char *oldargv[255];
9a3fa7
-static unsigned int oldargc = 0;
9a3fa7
-
9a3fa7
-/* arg meta data, were they quoted, frinstance */
9a3fa7
-static int newargvattr[255];
9a3fa7
-
9a3fa7
 #define XT_CHAIN_MAXNAMELEN XT_TABLE_MAXNAMELEN
9a3fa7
 static char closeActionTag[XT_TABLE_MAXNAMELEN + 1];
9a3fa7
 static char closeRuleTag[XT_TABLE_MAXNAMELEN + 1];
9a3fa7
@@ -93,56 +83,6 @@ struct chain {
9a3fa7
 static struct chain chains[maxChains];
9a3fa7
 static int nextChain = 0;
9a3fa7
 
9a3fa7
-/* funCtion adding one argument to newargv, updating newargc 
9a3fa7
- * returns true if argument added, false otherwise */
9a3fa7
-static int
9a3fa7
-add_argv(char *what, int quoted)
9a3fa7
-{
9a3fa7
-	DEBUGP("add_argv: %d %s\n", newargc, what);
9a3fa7
-	if (what && newargc + 1 < ARRAY_SIZE(newargv)) {
9a3fa7
-		newargv[newargc] = strdup(what);
9a3fa7
-		newargvattr[newargc] = quoted;
9a3fa7
-		newargc++;
9a3fa7
-		return 1;
9a3fa7
-	} else
9a3fa7
-		return 0;
9a3fa7
-}
9a3fa7
-
9a3fa7
-static void
9a3fa7
-free_argv(void)
9a3fa7
-{
9a3fa7
-	unsigned int i;
9a3fa7
-
9a3fa7
-	for (i = 0; i < newargc; i++) {
9a3fa7
-		free(newargv[i]);
9a3fa7
-		newargv[i] = NULL;
9a3fa7
-	}
9a3fa7
-	newargc = 0;
9a3fa7
-
9a3fa7
-	for (i = 0; i < oldargc; i++) {
9a3fa7
-		free(oldargv[i]);
9a3fa7
-		oldargv[i] = NULL;
9a3fa7
-	}
9a3fa7
-	oldargc = 0;
9a3fa7
-}
9a3fa7
-
9a3fa7
-/* save parsed rule for comparison with next rule 
9a3fa7
-   to perform action agregation on duplicate conditions */
9a3fa7
-static void
9a3fa7
-save_argv(void)
9a3fa7
-{
9a3fa7
-	unsigned int i;
9a3fa7
-
9a3fa7
-	for (i = 0; i < oldargc; i++)
9a3fa7
-		free(oldargv[i]);
9a3fa7
-	oldargc = newargc;
9a3fa7
-	newargc = 0;
9a3fa7
-	for (i = 0; i < oldargc; i++) {
9a3fa7
-		oldargv[i] = newargv[i];
9a3fa7
-		newargv[i] = NULL;
9a3fa7
-	}
9a3fa7
-}
9a3fa7
-
9a3fa7
 /* like puts but with xml encoding */
9a3fa7
 static void
9a3fa7
 xmlEncode(char *text)
9a3fa7
@@ -736,9 +676,6 @@ iptables_xml_main(int argc, char *argv[])
9a3fa7
 			int quote_open, quoted;
9a3fa7
 			char param_buffer[1024];
9a3fa7
 
9a3fa7
-			/* reset the newargv */
9a3fa7
-			newargc = 0;
9a3fa7
-
9a3fa7
 			if (buffer[0] == '[') {
9a3fa7
 				/* we have counters in our input */
9a3fa7
 				char *ptr = strchr(buffer, ']');
9a3fa7
diff --git a/iptables/xshared.c b/iptables/xshared.c
9a3fa7
index 742502154aa55..84dbea562576e 100644
9a3fa7
--- a/iptables/xshared.c
9a3fa7
+++ b/iptables/xshared.c
9a3fa7
@@ -406,3 +406,126 @@ void print_ipv6_addresses(const struct ip6t_entry *fw6, unsigned int format)
9a3fa7
 	       ipv6_addr_to_string(&fw6->ipv6.dst,
9a3fa7
 				   &fw6->ipv6.dmsk, format));
9a3fa7
 }
9a3fa7
+
9a3fa7
+/* global new argv and argc */
9a3fa7
+char *newargv[255];
9a3fa7
+int newargc = 0;
9a3fa7
+
9a3fa7
+/* saved newargv and newargc from save_argv() */
9a3fa7
+char *oldargv[255];
9a3fa7
+int oldargc = 0;
9a3fa7
+
9a3fa7
+/* arg meta data, were they quoted, frinstance */
9a3fa7
+int newargvattr[255];
9a3fa7
+
9a3fa7
+/* function adding one argument to newargv, updating newargc
9a3fa7
+ * returns true if argument added, false otherwise */
9a3fa7
+int add_argv(const char *what, int quoted)
9a3fa7
+{
9a3fa7
+	DEBUGP("add_argv: %s\n", what);
9a3fa7
+	if (what && newargc + 1 < ARRAY_SIZE(newargv)) {
9a3fa7
+		newargv[newargc] = strdup(what);
9a3fa7
+		newargvattr[newargc] = quoted;
9a3fa7
+		newargv[++newargc] = NULL;
9a3fa7
+		return 1;
9a3fa7
+	} else {
9a3fa7
+		xtables_error(PARAMETER_PROBLEM,
9a3fa7
+			      "Parser cannot handle more arguments\n");
9a3fa7
+	}
9a3fa7
+}
9a3fa7
+
9a3fa7
+void free_argv(void)
9a3fa7
+{
9a3fa7
+	while (newargc)
9a3fa7
+		free(newargv[--newargc]);
9a3fa7
+	while (oldargc)
9a3fa7
+		free(oldargv[--oldargc]);
9a3fa7
+}
9a3fa7
+
9a3fa7
+/* Save parsed rule for comparison with next rule to perform action aggregation
9a3fa7
+ * on duplicate conditions.
9a3fa7
+ */
9a3fa7
+void save_argv(void)
9a3fa7
+{
9a3fa7
+	unsigned int i;
9a3fa7
+
9a3fa7
+	while (oldargc)
9a3fa7
+		free(oldargv[--oldargc]);
9a3fa7
+
9a3fa7
+	oldargc = newargc;
9a3fa7
+	newargc = 0;
9a3fa7
+	for (i = 0; i < oldargc; i++) {
9a3fa7
+		oldargv[i] = newargv[i];
9a3fa7
+	}
9a3fa7
+}
9a3fa7
+
9a3fa7
+void add_param_to_argv(char *parsestart, int line)
9a3fa7
+{
9a3fa7
+	int quote_open = 0, escaped = 0, param_len = 0;
9a3fa7
+	char param_buffer[1024], *curchar;
9a3fa7
+
9a3fa7
+	/* After fighting with strtok enough, here's now
9a3fa7
+	 * a 'real' parser. According to Rusty I'm now no
9a3fa7
+	 * longer a real hacker, but I can live with that */
9a3fa7
+
9a3fa7
+	for (curchar = parsestart; *curchar; curchar++) {
9a3fa7
+		if (quote_open) {
9a3fa7
+			if (escaped) {
9a3fa7
+				param_buffer[param_len++] = *curchar;
9a3fa7
+				escaped = 0;
9a3fa7
+				continue;
9a3fa7
+			} else if (*curchar == '\\') {
9a3fa7
+				escaped = 1;
9a3fa7
+				continue;
9a3fa7
+			} else if (*curchar == '"') {
9a3fa7
+				quote_open = 0;
9a3fa7
+				*curchar = '"';
9a3fa7
+			} else {
9a3fa7
+				param_buffer[param_len++] = *curchar;
9a3fa7
+				continue;
9a3fa7
+			}
9a3fa7
+		} else {
9a3fa7
+			if (*curchar == '"') {
9a3fa7
+				quote_open = 1;
9a3fa7
+				continue;
9a3fa7
+			}
9a3fa7
+		}
9a3fa7
+
9a3fa7
+		switch (*curchar) {
9a3fa7
+		case '"':
9a3fa7
+			break;
9a3fa7
+		case ' ':
9a3fa7
+		case '\t':
9a3fa7
+		case '\n':
9a3fa7
+			if (!param_len) {
9a3fa7
+				/* two spaces? */
9a3fa7
+				continue;
9a3fa7
+			}
9a3fa7
+			break;
9a3fa7
+		default:
9a3fa7
+			/* regular character, copy to buffer */
9a3fa7
+			param_buffer[param_len++] = *curchar;
9a3fa7
+
9a3fa7
+			if (param_len >= sizeof(param_buffer))
9a3fa7
+				xtables_error(PARAMETER_PROBLEM,
9a3fa7
+					      "Parameter too long!");
9a3fa7
+			continue;
9a3fa7
+		}
9a3fa7
+
9a3fa7
+		param_buffer[param_len] = '\0';
9a3fa7
+
9a3fa7
+		/* check if table name specified */
9a3fa7
+		if ((param_buffer[0] == '-' &&
9a3fa7
+		     param_buffer[1] != '-' &&
9a3fa7
+		     strchr(param_buffer, 't')) ||
9a3fa7
+		    (!strncmp(param_buffer, "--t", 3) &&
9a3fa7
+		     !strncmp(param_buffer, "--table", strlen(param_buffer)))) {
9a3fa7
+			xtables_error(PARAMETER_PROBLEM,
9a3fa7
+				      "The -t option (seen in line %u) cannot be used in %s.\n",
9a3fa7
+				      line, xt_params->program_name);
9a3fa7
+		}
9a3fa7
+
9a3fa7
+		add_argv(param_buffer, 0);
9a3fa7
+		param_len = 0;
9a3fa7
+	}
9a3fa7
+}
9a3fa7
diff --git a/iptables/xshared.h b/iptables/xshared.h
9a3fa7
index bfdb10b2701e5..4f567db9f410b 100644
9a3fa7
--- a/iptables/xshared.h
9a3fa7
+++ b/iptables/xshared.h
9a3fa7
@@ -119,6 +119,19 @@ bool xs_has_arg(int argc, char *argv[]);
9a3fa7
 
9a3fa7
 extern const struct xtables_afinfo *afinfo;
9a3fa7
 
9a3fa7
+extern char *newargv[];
9a3fa7
+extern int newargc;
9a3fa7
+
9a3fa7
+extern char *oldargv[];
9a3fa7
+extern int oldargc;
9a3fa7
+
9a3fa7
+extern int newargvattr[];
9a3fa7
+
9a3fa7
+int add_argv(const char *what, int quoted);
9a3fa7
+void free_argv(void);
9a3fa7
+void save_argv(void);
9a3fa7
+void add_param_to_argv(char *parsestart, int line);
9a3fa7
+
9a3fa7
 void print_ipv4_addresses(const struct ipt_entry *fw, unsigned int format);
9a3fa7
 void print_ipv6_addresses(const struct ip6t_entry *fw6, unsigned int format);
9a3fa7
 
9a3fa7
-- 
9a3fa7
2.21.0
9a3fa7