From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pg0-f54.google.com (mail-pg0-f54.google.com [74.125.83.54]) by dpdk.org (Postfix) with ESMTP id 177CB90F1 for ; Mon, 21 Aug 2017 11:35:07 +0200 (CEST) Received: by mail-pg0-f54.google.com with SMTP id u191so22469023pgc.2 for ; Mon, 21 Aug 2017 02:35:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fridaylinux-org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=rfnttJIkmJo0fZcjcHXX9BulzM1rZ3rgsLjTauTSUB4=; b=jLpP4goFpx14p5FdQKtmm8RxUA6zu0hicS8OTEq/8hpD0uzrSN2dzCs0TLGZcHU008 LjcsrLovpLDob4HH0/046jvRBSumS2VTw3GIQW7WmTAJ6mtfGD23uFF7zZE+NFeTfYEQ qi2Xqz05XJDAKxqU/Szx9G+KRFpkYnaGCFjZ9u9EM84ePxgMbcyKyT3nij+1pcN6OwAT /OCyCHeNIwwZpF51qhqW/XSkGqLRCBjVfgEZhnnYl7WfPot0sMg2aqGf8mL4i2pUcDyX Iad8g79zLv8Vx35POYdM4ffhXcJd0NedBjmk1gt6EK1Td7f+jcVCohkFb3uOJR5ASI/y 1OIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=rfnttJIkmJo0fZcjcHXX9BulzM1rZ3rgsLjTauTSUB4=; b=BeJR+KKpME36/AfeQVSWe1A6lRnDholb74zAFCnlC0iSSBI5bA6+clR0jr9KXX7CxX zt0WGpY8k3cBj2zPe8zG1jfSwSUwT8173a8+U3QMHWbMNYHrLLKX8zwoUcYoZB6VwKw/ diUfxUomGEHhRs3LBis+H7EqOEv84eNyoido2UDGxeHne1bK4NHoGQI0LANP6z+KQD8P gCxUT0D56sPmMep5/pk6/5T4l1MsrpEGbAqA05j8KZkcFogLeaBbl/PjCXu99dHcuRXO vpjIkqByodWwUiux9v2IVrDe1+FI8a/0vOSPEpdodY3WNAhM1P6W+jyCJizKktr8bM7P d4pA== X-Gm-Message-State: AHYfb5jPqlsws32DNA3sfqdLZ42hgzYptYVB42o8XVJ+UiWbYJV+Yjct dKS0i6RVDlAVhUKOiXwkhQ== X-Received: by 10.99.1.203 with SMTP id 194mr15852917pgb.315.1503308107115; Mon, 21 Aug 2017 02:35:07 -0700 (PDT) Received: from localhost.localdomain ([45.63.61.64]) by smtp.gmail.com with ESMTPSA id 69sm23355087pfh.186.2017.08.21.02.35.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 21 Aug 2017 02:35:06 -0700 (PDT) From: Yuanhan Liu To: Adrien Mazarguil Cc: Bernard Iremonger , Olivier Matz , dpdk stable , Yuanhan Liu Date: Mon, 21 Aug 2017 17:30:38 +0800 Message-Id: <1503307878-16728-24-git-send-email-yliu@fridaylinux.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1503307878-16728-1-git-send-email-yliu@fridaylinux.org> References: <1503307878-16728-1-git-send-email-yliu@fridaylinux.org> Subject: [dpdk-stable] patch 'cmdline: fix dynamic tokens initialization' has been queued to stable release 17.05.2 X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 21 Aug 2017 09:35:08 -0000 Hi, FYI, your patch has been queued to stable release 17.05.2 Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet. It will be pushed if I get no objections before 08/24/17. So please shout if anyone has objections. Thanks. --yliu --- >>From c8634fa55469fbaf647f8f192aa73db32705a745 Mon Sep 17 00:00:00 2001 From: Adrien Mazarguil Date: Mon, 10 Jul 2017 14:09:34 +0200 Subject: [PATCH] cmdline: fix dynamic tokens initialization [ upstream commit f627b65cb0706cd3eb47a57f6de312c8605e3ba8 ] To avoid redundant calls to the token-generating function and provide it with helpful context, a temporary fixed-size array allocated on the stack of cmdline_parse() and cmdline_complete() keeps the address of preceding tokens for the command instance being processed (cmdline_parse_inst_t). Like the static tokens array in cmdline_parse_inst_t, it must be NULL-terminated, however this is not properly enforced as it is initialized once at the beginning of each function and a NULL terminator is never appended once replaced with generated tokens. When several commands rely on dynamic tokens, subsequent ones inherit an already initialized array whose tokens are not regenerated, which causes various issues such as mixed and repeated tokens from the first command. Enforcing NULL termination of the dynamic tokens array and reinitializing its first entry at each iteration solves these issues. Doing so is also less expensive than a full memset() at each iteration. Fixes: 4fffc05a2b2c ("cmdline: support dynamic tokens") Signed-off-by: Bernard Iremonger Signed-off-by: Adrien Mazarguil Acked-by: Olivier Matz --- lib/librte_cmdline/cmdline_parse.c | 78 ++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 42 deletions(-) diff --git a/lib/librte_cmdline/cmdline_parse.c b/lib/librte_cmdline/cmdline_parse.c index b814880..67e452d 100644 --- a/lib/librte_cmdline/cmdline_parse.c +++ b/lib/librte_cmdline/cmdline_parse.c @@ -139,6 +139,32 @@ nb_common_chars(const char * s1, const char * s2) return i; } +/** Retrieve either static or dynamic token at a given index. */ +static cmdline_parse_token_hdr_t * +get_token(cmdline_parse_inst_t *inst, + unsigned int index, + cmdline_parse_token_hdr_t + *(*dyn_tokens)[CMDLINE_PARSE_DYNAMIC_TOKENS]) +{ + /* check presence of static tokens first */ + if (inst->tokens[0] || !inst->f) + return inst->tokens[index]; + /* for dynamic tokens, make sure index does not overflow */ + if (index >= CMDLINE_PARSE_DYNAMIC_TOKENS - 1) + return NULL; + /* in case token is already generated, return it */ + if ((*dyn_tokens)[index]) + return (*dyn_tokens)[index]; + /* generate token */ + inst->f(&(*dyn_tokens)[index], NULL, dyn_tokens); + /* return immediately if there are no more tokens to expect */ + if (!(*dyn_tokens)[index]) + return NULL; + /* terminate list with a NULL entry */ + (*dyn_tokens)[index + 1] = NULL; + return (*dyn_tokens)[index]; +} + /** * try to match the buffer with an instruction (only the first * nb_match_token tokens if != 0). Return 0 if we match all the @@ -156,12 +182,7 @@ match_inst(cmdline_parse_inst_t *inst, const char *buf, int n = 0; struct cmdline_token_hdr token_hdr; - token_p = inst->tokens[token_num]; - if (!token_p && dyn_tokens && inst->f) { - if (!(*dyn_tokens)[0]) - inst->f(&(*dyn_tokens)[0], NULL, dyn_tokens); - token_p = (*dyn_tokens)[0]; - } + token_p = get_token(inst, token_num, dyn_tokens); if (token_p) memcpy(&token_hdr, token_p, sizeof(token_hdr)); @@ -203,17 +224,7 @@ match_inst(cmdline_parse_inst_t *inst, const char *buf, buf += n; token_num ++; - if (!inst->tokens[0]) { - if (token_num < (CMDLINE_PARSE_DYNAMIC_TOKENS - 1)) { - if (!(*dyn_tokens)[token_num]) - inst->f(&(*dyn_tokens)[token_num], - NULL, - dyn_tokens); - token_p = (*dyn_tokens)[token_num]; - } else - token_p = NULL; - } else - token_p = inst->tokens[token_num]; + token_p = get_token(inst, token_num, dyn_tokens); if (token_p) memcpy(&token_hdr, token_p, sizeof(token_hdr)); } @@ -276,7 +287,6 @@ cmdline_parse(struct cmdline *cl, const char * buf) return CMDLINE_PARSE_BAD_ARGS; ctx = cl->ctx; - memset(&dyn_tokens, 0, sizeof(dyn_tokens)); /* * - look if the buffer contains at least one line @@ -317,6 +327,7 @@ cmdline_parse(struct cmdline *cl, const char * buf) /* parse it !! */ inst = ctx[inst_num]; + dyn_tokens[0] = NULL; while (inst) { debug_printf("INST %d\n", inst_num); @@ -354,6 +365,7 @@ cmdline_parse(struct cmdline *cl, const char * buf) inst_num ++; inst = ctx[inst_num]; + dyn_tokens[0] = NULL; } /* call func */ @@ -400,7 +412,6 @@ cmdline_complete(struct cmdline *cl, const char *buf, int *state, debug_printf("%s called\n", __func__); memset(&token_hdr, 0, sizeof(token_hdr)); - memset(&dyn_tokens, 0, sizeof(dyn_tokens)); /* count the number of complete token to parse */ for (i=0 ; buf[i] ; i++) { @@ -421,6 +432,7 @@ cmdline_complete(struct cmdline *cl, const char *buf, int *state, nb_non_completable = 0; inst = ctx[inst_num]; + dyn_tokens[0] = NULL; while (inst) { /* parse the first tokens of the inst */ if (nb_token && @@ -429,18 +441,7 @@ cmdline_complete(struct cmdline *cl, const char *buf, int *state, goto next; debug_printf("instruction match\n"); - if (!inst->tokens[0]) { - if (nb_token < - (CMDLINE_PARSE_DYNAMIC_TOKENS - 1)) { - if (!dyn_tokens[nb_token]) - inst->f(&dyn_tokens[nb_token], - NULL, - &dyn_tokens); - token_p = dyn_tokens[nb_token]; - } else - token_p = NULL; - } else - token_p = inst->tokens[nb_token]; + token_p = get_token(inst, nb_token, &dyn_tokens); if (token_p) memcpy(&token_hdr, token_p, sizeof(token_hdr)); @@ -494,6 +495,7 @@ cmdline_complete(struct cmdline *cl, const char *buf, int *state, debug_printf("next\n"); inst_num ++; inst = ctx[inst_num]; + dyn_tokens[0] = NULL; } debug_printf("total choices %d for this completion\n", @@ -526,6 +528,7 @@ cmdline_complete(struct cmdline *cl, const char *buf, int *state, inst_num = 0; inst = ctx[inst_num]; + dyn_tokens[0] = NULL; while (inst) { /* we need to redo it */ inst = ctx[inst_num]; @@ -534,17 +537,7 @@ cmdline_complete(struct cmdline *cl, const char *buf, int *state, match_inst(inst, buf, nb_token, NULL, 0, &dyn_tokens)) goto next2; - if (!inst->tokens[0]) { - if (nb_token < (CMDLINE_PARSE_DYNAMIC_TOKENS - 1)) { - if (!dyn_tokens[nb_token]) - inst->f(&dyn_tokens[nb_token], - NULL, - &dyn_tokens); - token_p = dyn_tokens[nb_token]; - } else - token_p = NULL; - } else - token_p = inst->tokens[nb_token]; + token_p = get_token(inst, nb_token, &dyn_tokens); if (token_p) memcpy(&token_hdr, token_p, sizeof(token_hdr)); @@ -617,6 +610,7 @@ cmdline_complete(struct cmdline *cl, const char *buf, int *state, next2: inst_num ++; inst = ctx[inst_num]; + dyn_tokens[0] = NULL; } return 0; } -- 2.7.4