From: Garima Singh <garima.singh@xxxxxxxxxxxxx> In [1], Junio described a potential bug in sq_quote_buf_pretty() when the arg is a zero length string. It should emit quote-quote rather than nothing. This commit teaches sq_quote_buf_pretty to emit '' for null and empty strings. [1] https://public-inbox.org/git/pull.298.git.gitgitgadget@xxxxxxxxx/T/#m9e33936067ec2066f675aa63133a2486efd415fd Signed-off-by: Garima Singh <garima.singh@xxxxxxxxxxxxx> --- Makefile | 1 + quote.c | 9 +++++++ t/helper/test-quote.c | 28 +++++++++++++++++++++ t/helper/test-tool.c | 1 + t/helper/test-tool.h | 1 + t/t0091-quote.sh | 58 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 98 insertions(+) create mode 100644 t/helper/test-quote.c create mode 100755 t/t0091-quote.sh diff --git a/Makefile b/Makefile index f9255344ae..2d6a12db57 100644 --- a/Makefile +++ b/Makefile @@ -728,6 +728,7 @@ TEST_BUILTINS_OBJS += test-parse-options.o TEST_BUILTINS_OBJS += test-path-utils.o TEST_BUILTINS_OBJS += test-pkt-line.o TEST_BUILTINS_OBJS += test-prio-queue.o +TEST_BUILTINS_OBJS += test-quote.o TEST_BUILTINS_OBJS += test-reach.o TEST_BUILTINS_OBJS += test-read-cache.o TEST_BUILTINS_OBJS += test-read-midx.o diff --git a/quote.c b/quote.c index 7f2aa6faa4..84f61380fc 100644 --- a/quote.c +++ b/quote.c @@ -48,6 +48,15 @@ void sq_quote_buf_pretty(struct strbuf *dst, const char *src) static const char ok_punct[] = "+,-./:=@_^"; const char *p; + /* + * In case of null or empty tokens, add a '' to ensure we + * don't inadvertently drop those tokens + */ + if (!src || !*src) { + strbuf_addstr(dst, "''"); + return; + } + for (p = src; *p; p++) { if (!isalpha(*p) && !isdigit(*p) && !strchr(ok_punct, *p)) { sq_quote_buf(dst, src); diff --git a/t/helper/test-quote.c b/t/helper/test-quote.c new file mode 100644 index 0000000000..0266cc4fec --- /dev/null +++ b/t/helper/test-quote.c @@ -0,0 +1,28 @@ +#include "test-tool.h" +#include "quote.h" +#include "strbuf.h" +#include "string.h" + +int cmd__quote_buf_pretty(int argc, const char **argv) +{ + struct strbuf buf_payload = STRBUF_INIT; + + if (!argv[1]) { + strbuf_release(&buf_payload); + die("missing input string"); + } + + if (!strcmp(argv[1], "nullString")) + sq_quote_buf_pretty(&buf_payload, NULL); + + else if (!*argv[1]) + sq_quote_buf_pretty(&buf_payload, ""); + + else + sq_quote_buf_pretty(&buf_payload, argv[1]); + + /* Wrap the results in [] to make the test script more readable */ + printf("[%s]\n", buf_payload.buf); + strbuf_release(&buf_payload); + return 0; +} diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c index ce7e89028c..55ee1402dd 100644 --- a/t/helper/test-tool.c +++ b/t/helper/test-tool.c @@ -56,6 +56,7 @@ static struct test_cmd cmds[] = { { "sha1-array", cmd__sha1_array }, { "sha256", cmd__sha256 }, { "sigchain", cmd__sigchain }, + { "quote-buf-pretty", cmd__quote_buf_pretty }, { "strcmp-offset", cmd__strcmp_offset }, { "string-list", cmd__string_list }, { "submodule-config", cmd__submodule_config }, diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h index f805bb39ae..8c0affe89c 100644 --- a/t/helper/test-tool.h +++ b/t/helper/test-tool.h @@ -46,6 +46,7 @@ int cmd__sha1(int argc, const char **argv); int cmd__sha1_array(int argc, const char **argv); int cmd__sha256(int argc, const char **argv); int cmd__sigchain(int argc, const char **argv); +int cmd__quote_buf_pretty(int argc, const char **argv); int cmd__strcmp_offset(int argc, const char **argv); int cmd__string_list(int argc, const char **argv); int cmd__submodule_config(int argc, const char **argv); diff --git a/t/t0091-quote.sh b/t/t0091-quote.sh new file mode 100755 index 0000000000..a5515973c7 --- /dev/null +++ b/t/t0091-quote.sh @@ -0,0 +1,58 @@ +#!/bin/sh + +test_description='Testing the sq_quote_buf_pretty method in quote.c' +. ./test-lib.sh + +test_expect_success 'test method without input string' ' + test_must_fail test-tool quote-buf-pretty +' + +test_expect_success 'test null string' ' + cat >expect <<-EOF && + '[\'\']' + EOF + test-tool quote-buf-pretty nullString >actual && + test_cmp expect actual +' + +test_expect_success 'test empty string' ' + cat >expect <<-EOF && + '[\'\']' + EOF + test-tool quote-buf-pretty "" >actual && + test_cmp expect actual +' + +test_expect_success 'string without any punctuation' ' + cat >expect <<-EOF && + [testString] + EOF + test-tool quote-buf-pretty testString >actual && + test_cmp expect actual +' + +test_expect_success 'string with punctuation that do not require special quotes' ' + cat >expect <<-EOF && + [test+String] + EOF + test-tool quote-buf-pretty test+String >actual && + test_cmp expect actual +' + +test_expect_success 'string with punctuation that requires special quotes' ' + cat >expect <<-EOF && + '[\'test~String\']' + EOF + test-tool quote-buf-pretty test~String >actual && + test_cmp expect actual +' + +test_expect_success 'string with punctuation that requires special quotes' ' + cat >expect <<-EOF && + '[\'test\'\\!\'String\']' + EOF + test-tool quote-buf-pretty test!String >actual && + test_cmp expect actual +' + +test_done -- gitgitgadget