If argv[i] contains spaces, then restore the quotes on this string. There is one exception though: in case that argc == 2, then assume the whole input is coming as a quoted string, eg. nft "add rule x ...;add ..." This patch is adjusting a one test that uses quotes to skip escaping one semicolon from bash. Two more tests do not need them. Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> --- Currently nft accepts quotes everywhere, which makes things a bit tricky. I think this provides a model that can be documented and that skips quote escaping from bash. src/main.c | 30 +++++++++++++++++++--- tests/shell/testcases/flowtable/0007prio_0 | 2 +- tests/shell/testcases/sets/0034get_element_0 | 2 +- .../testcases/sets/0040get_host_endian_elements_0 | 12 ++++----- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/main.c b/src/main.c index 74199f93fa66..00ef999eaf4b 100644 --- a/src/main.c +++ b/src/main.c @@ -10,6 +10,7 @@ #include <stdlib.h> #include <stddef.h> +#include <ctype.h> #include <unistd.h> #include <stdio.h> #include <errno.h> @@ -243,10 +244,21 @@ static bool nft_options_check(int argc, char * const argv[]) return true; } +static bool nft_quoted_string(const char *arg) +{ + unsigned int i; + + for (i = 0; i < strlen(arg); i++) { + if (isspace(arg[i])) + return true; + } + return false; +} + int main(int argc, char * const *argv) { + unsigned int output_flags = 0, quotes; char *buf = NULL, *filename = NULL; - unsigned int output_flags = 0; bool interactive = false; unsigned int debug_mask; unsigned int len; @@ -365,8 +377,14 @@ int main(int argc, char * const *argv) nft_ctx_output_set_flags(nft, output_flags); if (optind != argc) { - for (len = 0, i = optind; i < argc; i++) - len += strlen(argv[i]) + strlen(" "); + for (len = 0, i = optind; i < argc; i++) { + if (argc != 2 && nft_quoted_string(argv[i])) + quotes = 2; + else + quotes = 0; + + len += strlen(argv[i]) + strlen(" ") + quotes; + } buf = calloc(1, len); if (buf == NULL) { @@ -375,7 +393,11 @@ int main(int argc, char * const *argv) exit(EXIT_FAILURE); } for (i = optind; i < argc; i++) { - strcat(buf, argv[i]); + if (argc != 2 && nft_quoted_string(argv[i])) + sprintf(buf + strlen(buf), "\"%s\"", argv[i]); + else + strcat(buf, argv[i]); + if (i + 1 < argc) strcat(buf, " "); } diff --git a/tests/shell/testcases/flowtable/0007prio_0 b/tests/shell/testcases/flowtable/0007prio_0 index 49bbcac7c93b..138fe4d58788 100755 --- a/tests/shell/testcases/flowtable/0007prio_0 +++ b/tests/shell/testcases/flowtable/0007prio_0 @@ -18,7 +18,7 @@ format_offset () { $NFT add table t for offset in -11 -10 0 10 11 do - $NFT add flowtable t f "{ hook ingress priority filter `format_offset $offset`; devices = { lo }; }" + $NFT add flowtable t f { hook ingress priority filter `format_offset $offset`\; devices = { lo }\; } $NFT delete flowtable t f done diff --git a/tests/shell/testcases/sets/0034get_element_0 b/tests/shell/testcases/sets/0034get_element_0 index c7e7298a4aac..47f93464b687 100755 --- a/tests/shell/testcases/sets/0034get_element_0 +++ b/tests/shell/testcases/sets/0034get_element_0 @@ -3,7 +3,7 @@ RC=0 check() { # (elems, expected) - out=$($NFT get element ip t s "{ $1 }" 2>/dev/null) + out=$($NFT get element ip t s { $1 } 2>/dev/null) out=$(grep "elements =" <<< "$out") out="${out#* \{ }" out="${out% \}}" diff --git a/tests/shell/testcases/sets/0040get_host_endian_elements_0 b/tests/shell/testcases/sets/0040get_host_endian_elements_0 index caf6a4af326a..889d28780be7 100755 --- a/tests/shell/testcases/sets/0040get_host_endian_elements_0 +++ b/tests/shell/testcases/sets/0040get_host_endian_elements_0 @@ -12,32 +12,32 @@ RULESET="table ip t { $NFT -f - <<< "$RULESET" || { echo "can't apply basic ruleset"; exit 1; } -$NFT get element ip t s '{ 0x23-0x42 }' || { +$NFT get element ip t s { 0x23-0x42 } || { echo "can't find existing range 0x23-0x42" exit 1 } -$NFT get element ip t s '{ 0x26-0x28 }' || { +$NFT get element ip t s { 0x26-0x28 } || { echo "can't find existing sub-range 0x26-0x28" exit 1 } -$NFT get element ip t s '{ 0x26-0x99 }' && { +$NFT get element ip t s { 0x26-0x99 } && { echo "found non-existing range 0x26-0x99" exit 1 } -$NFT get element ip t s '{ 0x55-0x99 }' && { +$NFT get element ip t s { 0x55-0x99 } && { echo "found non-existing range 0x55-0x99" exit 1 } -$NFT get element ip t s '{ 0x55 }' && { +$NFT get element ip t s { 0x55 } && { echo "found non-existing element 0x55" exit 1 } -$NFT get element ip t s '{ 0x1337 }' || { +$NFT get element ip t s { 0x1337 } || { echo "can't find existing element 0x1337" exit 1 } -- 2.11.0