From 3b7cec365af342697017796eac63bff7fb56e1c6 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Wed, 18 Oct 2023 10:27:12 +0200 Subject: [PATCH 1/3] Support double-quoted arguments in CLI When a quoted command argument is seen, it will take all characters until the next double-quote (no supported escape sequence here for simplicity). All white spaces (space, tab, etc.) are then removed from the argument. This means that the following command should behave the same: ``` pm3> wiegand encode --fc 101 --cn 1337 pm3> wiegand encode --fc "1 0 1" --cn "1 3 3 7" ``` Or a more useful example, when copy/pasting hex formatted values: ``` pm3> hf iclass calcnewkey --old 1122334455667788 --new 2233445566778899 pm3> hf iclass calcnewkey --old "11 22 33 44 55 66 77 88" --new "22 33 44 55 66 77 88 99" ``` --- client/deps/cliparser/cliparser.c | 34 +++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/client/deps/cliparser/cliparser.c b/client/deps/cliparser/cliparser.c index e5e8f946c..c11863ab6 100644 --- a/client/deps/cliparser/cliparser.c +++ b/client/deps/cliparser/cliparser.c @@ -147,6 +147,7 @@ enum ParserState { PS_FIRST, PS_ARGUMENT, PS_OPTION, + PS_QUOTE, }; #define isSpace(c)(c == ' ' || c == '\t') @@ -195,6 +196,10 @@ int CLIParserParseStringEx(CLIParserContext *ctx, const char *str, void *vargtab case PS_ARGUMENT: if (state == PS_FIRST) state = PS_ARGUMENT; + if (str[i] == '"') { + state = PS_QUOTE; + break; + } if (isSpace(str[i])) { spaceptr = bufptr; state = PS_FIRST; @@ -215,6 +220,35 @@ int CLIParserParseStringEx(CLIParserContext *ctx, const char *str, void *vargtab *bufptr = str[i]; bufptr++; break; + case PS_QUOTE: + if (str[i] == '"') { + // Now let's compact the argument by removing spaces + if (spaceptr != NULL) { + // We've seen at least 1 space + char *cur_ptr = spaceptr; + while (spaceptr < bufptr) { + if (isSpace(*spaceptr) == false) { + *cur_ptr = *spaceptr; + cur_ptr++; + } + spaceptr++; + } + *cur_ptr = 0; + // Rollback bufptr + bufptr = cur_ptr; + spaceptr = NULL; + } + *bufptr = 0x00; + state = PS_FIRST; + } else { + if (isSpace(str[i]) && spaceptr == NULL) { + // Store first encountered space for later + spaceptr = bufptr; + } + *bufptr = str[i]; + } + bufptr++; + break; } if (bufptr > bufptrend) { PrintAndLogEx(ERR, "ERROR: Line too long\n"); From 238faaf226432a2f4499ebbfc7ee8bd13181211c Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Wed, 18 Oct 2023 10:32:18 +0200 Subject: [PATCH 2/3] Add entry to CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7bc571b5a..6a711b51c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add support for quoted arguments in the CLI, allowing spaces in them which + are removed automatically (@jmichelp) - Added UDP support on Windows (@wh201906) - Added client communication timeout to preferences (@iceman1001) - Added IPv6 support (@wh201906) From dbe041231185e3aca57a8bd77636a73c7dff39fd Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Wed, 18 Oct 2023 10:38:33 +0200 Subject: [PATCH 3/3] Simplify quote handling --- client/deps/cliparser/cliparser.c | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/client/deps/cliparser/cliparser.c b/client/deps/cliparser/cliparser.c index c11863ab6..0ea0bd33b 100644 --- a/client/deps/cliparser/cliparser.c +++ b/client/deps/cliparser/cliparser.c @@ -222,32 +222,13 @@ int CLIParserParseStringEx(CLIParserContext *ctx, const char *str, void *vargtab break; case PS_QUOTE: if (str[i] == '"') { - // Now let's compact the argument by removing spaces - if (spaceptr != NULL) { - // We've seen at least 1 space - char *cur_ptr = spaceptr; - while (spaceptr < bufptr) { - if (isSpace(*spaceptr) == false) { - *cur_ptr = *spaceptr; - cur_ptr++; - } - spaceptr++; - } - *cur_ptr = 0; - // Rollback bufptr - bufptr = cur_ptr; - spaceptr = NULL; - } - *bufptr = 0x00; + *bufptr++ = 0x00; state = PS_FIRST; } else { - if (isSpace(str[i]) && spaceptr == NULL) { - // Store first encountered space for later - spaceptr = bufptr; + if (isSpace(str[i]) == false) { + *bufptr++ = str[i]; } - *bufptr = str[i]; } - bufptr++; break; } if (bufptr > bufptrend) {