[dpdk-dev,v3,3/3] app/testpmd: fix token matching in flow command

Message ID 2065c72b2ec6e1377beff72d246ae23fb533ab78.1499687422.git.adrien.mazarguil@6wind.com (mailing list archive)
State Accepted, archived
Delegated to: Thomas Monjalon
Headers

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation fail Compilation issues

Commit Message

Adrien Mazarguil July 10, 2017, 12:09 p.m. UTC
  While matching user input against a token name or any other fixed string,
comparison stops at the end of user input if shorter (e.g. "foo" matches
token name "foobar").

Although the unintended consequence of this behavior allows users to
abbreviate command names and various parameters yet generate valid
commands, the parser was not designed to support this and does not prevent
ambiguous tokens.

For instance, entering "i" for a pattern item matches "ipv4", "ipv6" and
"icmp" then defaults to one of them in an unspecified manner.

Prevent this behavior by taking the length of fixed strings into account.

Fixes: 19c90af6285c ("app/testpmd: add flow command")
Fixes: 5ac3502ed1be ("app/testpmd: add flow query command")
Fixes: abc3d81aca1b ("app/testpmd: add item raw to flow command")
Fixes: 05d34c6e9d2c ("app/testpmd: add queue actions to flow command")
Cc: stable@dpdk.org

Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
 app/test-pmd/cmdline_flow.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)
  

Patch

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 9533df1..a17a004 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -1624,6 +1624,19 @@  arg_entry_bf_fill(void *dst, uintmax_t val, const struct arg *arg)
 	return len;
 }
 
+/** Compare a string with a partial one of a given length. */
+static int
+strcmp_partial(const char *full, const char *partial, size_t partial_len)
+{
+	int r = strncmp(full, partial, partial_len);
+
+	if (r)
+		return r;
+	if (strlen(full) <= partial_len)
+		return 0;
+	return full[partial_len];
+}
+
 /**
  * Parse a prefix length and generate a bit-mask.
  *
@@ -1706,7 +1719,7 @@  parse_default(struct context *ctx, const struct token *token,
 	(void)ctx;
 	(void)buf;
 	(void)size;
-	if (strncmp(str, token->name, len))
+	if (strcmp_partial(token->name, str, len))
 		return -1;
 	return len;
 }
@@ -1949,7 +1962,7 @@  parse_vc_action_rss_queue(struct context *ctx, const struct token *token,
 	if (ctx->curr != ACTION_RSS_QUEUE)
 		return -1;
 	i = ctx->objdata >> 16;
-	if (!strncmp(str, "end", len)) {
+	if (!strcmp_partial("end", str, len)) {
 		ctx->objdata &= 0xffff;
 		return len;
 	}
@@ -2084,7 +2097,7 @@  parse_action(struct context *ctx, const struct token *token,
 		const struct parse_action_priv *priv;
 
 		token = &token_list[next_action[i]];
-		if (strncmp(token->name, str, len))
+		if (strcmp_partial(token->name, str, len))
 			continue;
 		priv = token->priv;
 		if (!priv)
@@ -2451,7 +2464,7 @@  parse_boolean(struct context *ctx, const struct token *token,
 	if (!arg)
 		return -1;
 	for (i = 0; boolean_name[i]; ++i)
-		if (!strncmp(str, boolean_name[i], len))
+		if (!strcmp_partial(boolean_name[i], str, len))
 			break;
 	/* Process token as integer. */
 	if (boolean_name[i])