mirror of
https://github.com/tailix/libkernaux.git
synced 2024-11-13 11:04:27 -05:00
Implement escaping inside quotes in cmd line parser
This commit is contained in:
parent
2b7fda767d
commit
5504054a22
2 changed files with 94 additions and 33 deletions
|
@ -14,6 +14,7 @@ enum State {
|
|||
TOKEN,
|
||||
BACKSLASH,
|
||||
QUOTE,
|
||||
QUOTE_BACKSLASH,
|
||||
};
|
||||
|
||||
bool kernaux_cmdline_parse(
|
||||
|
@ -206,6 +207,9 @@ bool kernaux_cmdline_parse(
|
|||
kernaux_strncpy(error_msg, "EOL inside quote", 16);
|
||||
goto fail;
|
||||
}
|
||||
else if (cur == '\\') {
|
||||
state = QUOTE_BACKSLASH;
|
||||
}
|
||||
else if (cur == '"') {
|
||||
if (buffer_size >= arg_size_max) {
|
||||
kernaux_strncpy(error_msg, "arg too long", 12);
|
||||
|
@ -226,6 +230,23 @@ bool kernaux_cmdline_parse(
|
|||
++buffer_size;
|
||||
}
|
||||
break;
|
||||
|
||||
case QUOTE_BACKSLASH:
|
||||
if (cur == '\0') {
|
||||
kernaux_strncpy(error_msg, "EOL after backslash inside quote", 32);
|
||||
goto fail;
|
||||
}
|
||||
else {
|
||||
if (buffer_size >= arg_size_max) {
|
||||
kernaux_strncpy(error_msg, "arg too long", 12);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
state = QUOTE;
|
||||
*(buffer++) = cur;
|
||||
++buffer_size;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (state == FINAL) {
|
||||
|
|
|
@ -119,39 +119,72 @@ int main()
|
|||
test("\"foo\" \"bar\" \"car\"", 0, 3, false, "arg too long", 0, argv0);
|
||||
test("\"foo\" \"bar\" \"car\"", 2, 3, false, "arg too long", 0, argv0);
|
||||
|
||||
test("\\ ", 0, 0, true, "", 1, argv_space);
|
||||
test("\\\\", 0, 0, true, "", 1, argv_backslash);
|
||||
test("\\\"", 0, 0, true, "", 1, argv_quotmark);
|
||||
test("foo\\ ", 0, 0, true, "", 1, argv_foospace);
|
||||
test("foo\\\\", 0, 0, true, "", 1, argv_foobackslash);
|
||||
test("foo\\\"", 0, 0, true, "", 1, argv_fooquotmark);
|
||||
test("\\ foo", 0, 0, true, "", 1, argv_spacefoo);
|
||||
test("\\\\foo", 0, 0, true, "", 1, argv_backslashfoo);
|
||||
test("\\\"foo", 0, 0, true, "", 1, argv_quotmarkfoo);
|
||||
test("\\ foo\\ ", 0, 0, true, "", 1, argv_spacefoospace);
|
||||
test("\\\\foo\\\\", 0, 0, true, "", 1, argv_backslashfoobackslash);
|
||||
test("\\\"foo\\\"", 0, 0, true, "", 1, argv_quotmarkfooquotmark);
|
||||
test("foo\\ bar", 0, 0, true, "", 1, argv_foospacebar);
|
||||
test("foo\\\\bar", 0, 0, true, "", 1, argv_foobackslashbar);
|
||||
test("foo\\\"bar", 0, 0, true, "", 1, argv_fooquotmarkbar);
|
||||
test("\\ foo bar", 0, 0, true, "", 2, argv_spacefoo_bar);
|
||||
test("\\\\foo bar", 0, 0, true, "", 2, argv_backslashfoo_bar);
|
||||
test("\\\"foo bar", 0, 0, true, "", 2, argv_quotmarkfoo_bar);
|
||||
test("foo\\ bar", 0, 0, true, "", 2, argv_foospace_bar);
|
||||
test("foo\\\\ bar", 0, 0, true, "", 2, argv_foobackslash_bar);
|
||||
test("foo\\\" bar", 0, 0, true, "", 2, argv_fooquotmark_bar);
|
||||
test("\\ foo\\ bar", 0, 0, true, "", 2, argv_spacefoospace_bar);
|
||||
test("\\\\foo\\\\ bar", 0, 0, true, "", 2, argv_backslashfoobackslash_bar);
|
||||
test("\\\"foo\\\" bar", 0, 0, true, "", 2, argv_quotmarkfooquotmark_bar);
|
||||
test("foo \\ bar", 0, 0, true, "", 2, argv_foo_spacebar);
|
||||
test("foo \\\\bar", 0, 0, true, "", 2, argv_foo_backslashbar);
|
||||
test("foo \\\"bar", 0, 0, true, "", 2, argv_foo_quotmarkbar);
|
||||
test("foo bar\\ ", 0, 0, true, "", 2, argv_foo_barspace);
|
||||
test("foo bar\\\\", 0, 0, true, "", 2, argv_foo_barbackslash);
|
||||
test("foo bar\\\"", 0, 0, true, "", 2, argv_foo_barquotmark);
|
||||
test("foo \\ bar\\ ", 0, 0, true, "", 2, argv_foo_spacebarspace);
|
||||
test("foo \\\\bar\\\\", 0, 0, true, "", 2, argv_foo_backslashbarbackslash);
|
||||
test("foo \\\"bar\\\"", 0, 0, true, "", 2, argv_foo_quotmarkbarquotmark);
|
||||
test("\\ ", 0, 0, true, "", 1, argv_space);
|
||||
test("\"\\ \"", 0, 0, true, "", 1, argv_space);
|
||||
test("\\\\", 0, 0, true, "", 1, argv_backslash);
|
||||
test("\"\\\\\"", 0, 0, true, "", 1, argv_backslash);
|
||||
test("\\\"", 0, 0, true, "", 1, argv_quotmark);
|
||||
test("\"\\\"\"", 0, 0, true, "", 1, argv_quotmark);
|
||||
test("foo\\ ", 0, 0, true, "", 1, argv_foospace);
|
||||
test("\"foo\\ \"", 0, 0, true, "", 1, argv_foospace);
|
||||
test("foo\\\\", 0, 0, true, "", 1, argv_foobackslash);
|
||||
test("\"foo\\\\\"", 0, 0, true, "", 1, argv_foobackslash);
|
||||
test("foo\\\"", 0, 0, true, "", 1, argv_fooquotmark);
|
||||
test("\"foo\\\"\"", 0, 0, true, "", 1, argv_fooquotmark);
|
||||
test("\\ foo", 0, 0, true, "", 1, argv_spacefoo);
|
||||
test("\"\\ foo\"", 0, 0, true, "", 1, argv_spacefoo);
|
||||
test("\\\\foo", 0, 0, true, "", 1, argv_backslashfoo);
|
||||
test("\"\\\\foo\"", 0, 0, true, "", 1, argv_backslashfoo);
|
||||
test("\\\"foo", 0, 0, true, "", 1, argv_quotmarkfoo);
|
||||
test("\"\\\"foo\"", 0, 0, true, "", 1, argv_quotmarkfoo);
|
||||
test("\\ foo\\ ", 0, 0, true, "", 1, argv_spacefoospace);
|
||||
test("\"\\ foo\\ \"", 0, 0, true, "", 1, argv_spacefoospace);
|
||||
test("\\\\foo\\\\", 0, 0, true, "", 1, argv_backslashfoobackslash);
|
||||
test("\"\\\\foo\\\\\"", 0, 0, true, "", 1, argv_backslashfoobackslash);
|
||||
test("\\\"foo\\\"", 0, 0, true, "", 1, argv_quotmarkfooquotmark);
|
||||
test("\"\\\"foo\\\"\"", 0, 0, true, "", 1, argv_quotmarkfooquotmark);
|
||||
test("foo\\ bar", 0, 0, true, "", 1, argv_foospacebar);
|
||||
test("\"foo\\ bar\"", 0, 0, true, "", 1, argv_foospacebar);
|
||||
test("foo\\\\bar", 0, 0, true, "", 1, argv_foobackslashbar);
|
||||
test("\"foo\\\\bar\"", 0, 0, true, "", 1, argv_foobackslashbar);
|
||||
test("foo\\\"bar", 0, 0, true, "", 1, argv_fooquotmarkbar);
|
||||
test("\"foo\\\"bar\"", 0, 0, true, "", 1, argv_fooquotmarkbar);
|
||||
test("\\ foo bar", 0, 0, true, "", 2, argv_spacefoo_bar);
|
||||
test("\"\\ foo\" bar", 0, 0, true, "", 2, argv_spacefoo_bar);
|
||||
test("\\\\foo bar", 0, 0, true, "", 2, argv_backslashfoo_bar);
|
||||
test("\"\\\\foo\" bar", 0, 0, true, "", 2, argv_backslashfoo_bar);
|
||||
test("\\\"foo bar", 0, 0, true, "", 2, argv_quotmarkfoo_bar);
|
||||
test("\"\\\"foo\" bar", 0, 0, true, "", 2, argv_quotmarkfoo_bar);
|
||||
test("foo\\ bar", 0, 0, true, "", 2, argv_foospace_bar);
|
||||
test("\"foo\\ \" bar", 0, 0, true, "", 2, argv_foospace_bar);
|
||||
test("foo\\\\ bar", 0, 0, true, "", 2, argv_foobackslash_bar);
|
||||
test("\"foo\\\\\" bar", 0, 0, true, "", 2, argv_foobackslash_bar);
|
||||
test("foo\\\" bar", 0, 0, true, "", 2, argv_fooquotmark_bar);
|
||||
test("\"foo\\\"\" bar", 0, 0, true, "", 2, argv_fooquotmark_bar);
|
||||
test("\\ foo\\ bar", 0, 0, true, "", 2, argv_spacefoospace_bar);
|
||||
test("\"\\ foo\\ \" bar", 0, 0, true, "", 2, argv_spacefoospace_bar);
|
||||
test("\\\\foo\\\\ bar", 0, 0, true, "", 2, argv_backslashfoobackslash_bar);
|
||||
test("\"\\\\foo\\\\\" bar", 0, 0, true, "", 2, argv_backslashfoobackslash_bar);
|
||||
test("\\\"foo\\\" bar", 0, 0, true, "", 2, argv_quotmarkfooquotmark_bar);
|
||||
test("\"\\\"foo\\\"\" bar", 0, 0, true, "", 2, argv_quotmarkfooquotmark_bar);
|
||||
test("foo \\ bar", 0, 0, true, "", 2, argv_foo_spacebar);
|
||||
test("foo \"\\ bar\"", 0, 0, true, "", 2, argv_foo_spacebar);
|
||||
test("foo \\\\bar", 0, 0, true, "", 2, argv_foo_backslashbar);
|
||||
test("foo \"\\\\bar\"", 0, 0, true, "", 2, argv_foo_backslashbar);
|
||||
test("foo \\\"bar", 0, 0, true, "", 2, argv_foo_quotmarkbar);
|
||||
test("foo \"\\\"bar\"", 0, 0, true, "", 2, argv_foo_quotmarkbar);
|
||||
test("foo bar\\ ", 0, 0, true, "", 2, argv_foo_barspace);
|
||||
test("foo \"bar\\ \"", 0, 0, true, "", 2, argv_foo_barspace);
|
||||
test("foo bar\\\\", 0, 0, true, "", 2, argv_foo_barbackslash);
|
||||
test("foo \"bar\\\\\"", 0, 0, true, "", 2, argv_foo_barbackslash);
|
||||
test("foo bar\\\"", 0, 0, true, "", 2, argv_foo_barquotmark);
|
||||
test("foo \"bar\\\"\"", 0, 0, true, "", 2, argv_foo_barquotmark);
|
||||
test("foo \\ bar\\ ", 0, 0, true, "", 2, argv_foo_spacebarspace);
|
||||
test("foo \"\\ bar\\ \"", 0, 0, true, "", 2, argv_foo_spacebarspace);
|
||||
test("foo \\\\bar\\\\", 0, 0, true, "", 2, argv_foo_backslashbarbackslash);
|
||||
test("foo \"\\\\bar\\\\\"", 0, 0, true, "", 2, argv_foo_backslashbarbackslash);
|
||||
test("foo \\\"bar\\\"", 0, 0, true, "", 2, argv_foo_quotmarkbarquotmark);
|
||||
test("foo \"\\\"bar\\\"\"", 0, 0, true, "", 2, argv_foo_quotmarkbarquotmark);
|
||||
|
||||
test("foo\\ bar car", 0, 0, true, "", 2, argv_foospacebar_car);
|
||||
test("\"foo bar\" car", 0, 0, true, "", 2, argv_foospacebar_car);
|
||||
|
@ -187,6 +220,13 @@ int main()
|
|||
test("\\\"\\", 0, 0, false, "EOL after backslash", 0, argv0);
|
||||
test("foo\\", 0, 0, false, "EOL after backslash", 0, argv0);
|
||||
|
||||
test("\"\\", 0, 0, false, "EOL after backslash inside quote", 0, argv0);
|
||||
test("\" \\", 0, 0, false, "EOL after backslash inside quote", 0, argv0);
|
||||
test("\"\\ \\", 0, 0, false, "EOL after backslash inside quote", 0, argv0);
|
||||
test("\"\\\\\\", 0, 0, false, "EOL after backslash inside quote", 0, argv0);
|
||||
test("\"\\\"\\", 0, 0, false, "EOL after backslash inside quote", 0, argv0);
|
||||
test("\"foo\\", 0, 0, false, "EOL after backslash inside quote", 0, argv0);
|
||||
|
||||
test("foo\"", 0, 0, false, "unescaped quotation mark", 0, argv0);
|
||||
test("foo\"bar", 0, 0, false, "unescaped quotation mark", 0, argv0);
|
||||
|
||||
|
|
Loading…
Reference in a new issue