xref: /llvm-project/lldb/unittests/Utility/ArgsTest.cpp (revision 70599d70273b671b1b2e6a0e0b9c11e413209647)
180814287SRaphael Isemann //===-- ArgsTest.cpp ------------------------------------------------------===//
2145d95c9SPavel Labath //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6145d95c9SPavel Labath //
7145d95c9SPavel Labath //===----------------------------------------------------------------------===//
8145d95c9SPavel Labath 
9145d95c9SPavel Labath #include "gtest/gtest.h"
10145d95c9SPavel Labath 
11145d95c9SPavel Labath #include "lldb/Utility/Args.h"
12bb1d702eSRaphael Isemann #include "lldb/Utility/FileSpec.h"
13145d95c9SPavel Labath #include "lldb/Utility/StringList.h"
14145d95c9SPavel Labath 
15145d95c9SPavel Labath #include <limits>
16145d95c9SPavel Labath #include <sstream>
17145d95c9SPavel Labath 
18145d95c9SPavel Labath using namespace lldb_private;
19145d95c9SPavel Labath 
TEST(ArgsTest,TestSingleArg)20145d95c9SPavel Labath TEST(ArgsTest, TestSingleArg) {
21145d95c9SPavel Labath   Args args;
22145d95c9SPavel Labath   args.SetCommandString("arg");
23145d95c9SPavel Labath   EXPECT_EQ(1u, args.GetArgumentCount());
24145d95c9SPavel Labath   EXPECT_STREQ(args.GetArgumentAtIndex(0), "arg");
25145d95c9SPavel Labath }
26145d95c9SPavel Labath 
TEST(ArgsTest,TestSingleQuotedArgWithSpace)27145d95c9SPavel Labath TEST(ArgsTest, TestSingleQuotedArgWithSpace) {
28145d95c9SPavel Labath   Args args;
29145d95c9SPavel Labath   args.SetCommandString("\"arg with space\"");
30145d95c9SPavel Labath   EXPECT_EQ(1u, args.GetArgumentCount());
31145d95c9SPavel Labath   EXPECT_STREQ(args.GetArgumentAtIndex(0), "arg with space");
32145d95c9SPavel Labath }
33145d95c9SPavel Labath 
TEST(ArgsTest,TestSingleArgWithQuotedSpace)34145d95c9SPavel Labath TEST(ArgsTest, TestSingleArgWithQuotedSpace) {
35145d95c9SPavel Labath   Args args;
36145d95c9SPavel Labath   args.SetCommandString("arg\\ with\\ space");
37145d95c9SPavel Labath   EXPECT_EQ(1u, args.GetArgumentCount());
38145d95c9SPavel Labath   EXPECT_STREQ(args.GetArgumentAtIndex(0), "arg with space");
39145d95c9SPavel Labath }
40145d95c9SPavel Labath 
TEST(ArgsTest,TestTrailingBackslash)410d50c4e0SRaphael Isemann TEST(ArgsTest, TestTrailingBackslash) {
420d50c4e0SRaphael Isemann   Args args;
430d50c4e0SRaphael Isemann   args.SetCommandString("arg\\");
440d50c4e0SRaphael Isemann   EXPECT_EQ(1u, args.GetArgumentCount());
450d50c4e0SRaphael Isemann   EXPECT_STREQ(args.GetArgumentAtIndex(0), "arg\\");
460d50c4e0SRaphael Isemann }
470d50c4e0SRaphael Isemann 
TEST(ArgsTest,TestQuotedTrailingBackslash)480d50c4e0SRaphael Isemann TEST(ArgsTest, TestQuotedTrailingBackslash) {
490d50c4e0SRaphael Isemann   Args args;
500d50c4e0SRaphael Isemann   args.SetCommandString("\"arg\\");
510d50c4e0SRaphael Isemann   EXPECT_EQ(1u, args.GetArgumentCount());
520d50c4e0SRaphael Isemann   EXPECT_STREQ(args.GetArgumentAtIndex(0), "arg\\");
530d50c4e0SRaphael Isemann }
540d50c4e0SRaphael Isemann 
TEST(ArgsTest,TestUnknownEscape)550d50c4e0SRaphael Isemann TEST(ArgsTest, TestUnknownEscape) {
560d50c4e0SRaphael Isemann   Args args;
570d50c4e0SRaphael Isemann   args.SetCommandString("arg\\y");
580d50c4e0SRaphael Isemann   EXPECT_EQ(1u, args.GetArgumentCount());
590d50c4e0SRaphael Isemann   EXPECT_STREQ(args.GetArgumentAtIndex(0), "arg\\y");
600d50c4e0SRaphael Isemann }
610d50c4e0SRaphael Isemann 
TEST(ArgsTest,TestQuotedUnknownEscape)620d50c4e0SRaphael Isemann TEST(ArgsTest, TestQuotedUnknownEscape) {
630d50c4e0SRaphael Isemann   Args args;
640d50c4e0SRaphael Isemann   args.SetCommandString("\"arg\\y");
650d50c4e0SRaphael Isemann   EXPECT_EQ(1u, args.GetArgumentCount());
660d50c4e0SRaphael Isemann   EXPECT_STREQ(args.GetArgumentAtIndex(0), "arg\\y");
670d50c4e0SRaphael Isemann }
680d50c4e0SRaphael Isemann 
TEST(ArgsTest,TestMultipleArgs)69145d95c9SPavel Labath TEST(ArgsTest, TestMultipleArgs) {
70145d95c9SPavel Labath   Args args;
71145d95c9SPavel Labath   args.SetCommandString("this has multiple args");
72145d95c9SPavel Labath   EXPECT_EQ(4u, args.GetArgumentCount());
73145d95c9SPavel Labath   EXPECT_STREQ(args.GetArgumentAtIndex(0), "this");
74145d95c9SPavel Labath   EXPECT_STREQ(args.GetArgumentAtIndex(1), "has");
75145d95c9SPavel Labath   EXPECT_STREQ(args.GetArgumentAtIndex(2), "multiple");
76145d95c9SPavel Labath   EXPECT_STREQ(args.GetArgumentAtIndex(3), "args");
77145d95c9SPavel Labath }
78145d95c9SPavel Labath 
TEST(ArgsTest,TestOverwriteArgs)79145d95c9SPavel Labath TEST(ArgsTest, TestOverwriteArgs) {
80145d95c9SPavel Labath   Args args;
81145d95c9SPavel Labath   args.SetCommandString("this has multiple args");
82145d95c9SPavel Labath   EXPECT_EQ(4u, args.GetArgumentCount());
83145d95c9SPavel Labath   args.SetCommandString("arg");
84145d95c9SPavel Labath   EXPECT_EQ(1u, args.GetArgumentCount());
85145d95c9SPavel Labath   EXPECT_STREQ(args.GetArgumentAtIndex(0), "arg");
86145d95c9SPavel Labath }
87145d95c9SPavel Labath 
TEST(ArgsTest,TestAppendArg)88145d95c9SPavel Labath TEST(ArgsTest, TestAppendArg) {
89145d95c9SPavel Labath   Args args;
90145d95c9SPavel Labath   args.SetCommandString("first_arg");
91145d95c9SPavel Labath   EXPECT_EQ(1u, args.GetArgumentCount());
92145d95c9SPavel Labath   args.AppendArgument(llvm::StringRef("second_arg"));
93145d95c9SPavel Labath   EXPECT_EQ(2u, args.GetArgumentCount());
94145d95c9SPavel Labath   EXPECT_STREQ(args.GetArgumentAtIndex(0), "first_arg");
95145d95c9SPavel Labath   EXPECT_STREQ(args.GetArgumentAtIndex(1), "second_arg");
96145d95c9SPavel Labath }
97145d95c9SPavel Labath 
TEST(ArgsTest,TestInsertArg)98145d95c9SPavel Labath TEST(ArgsTest, TestInsertArg) {
99145d95c9SPavel Labath   Args args;
100145d95c9SPavel Labath   args.AppendArgument("1");
101145d95c9SPavel Labath   args.AppendArgument("2");
102145d95c9SPavel Labath   args.AppendArgument("3");
103145d95c9SPavel Labath   args.InsertArgumentAtIndex(1, "1.5");
104145d95c9SPavel Labath   args.InsertArgumentAtIndex(4, "3.5");
105145d95c9SPavel Labath 
106145d95c9SPavel Labath   ASSERT_EQ(5u, args.GetArgumentCount());
107145d95c9SPavel Labath   EXPECT_STREQ("1", args.GetArgumentAtIndex(0));
108145d95c9SPavel Labath   EXPECT_STREQ("1.5", args.GetArgumentAtIndex(1));
109145d95c9SPavel Labath   EXPECT_STREQ("2", args.GetArgumentAtIndex(2));
110145d95c9SPavel Labath   EXPECT_STREQ("3", args.GetArgumentAtIndex(3));
111145d95c9SPavel Labath   EXPECT_STREQ("3.5", args.GetArgumentAtIndex(4));
112145d95c9SPavel Labath }
113145d95c9SPavel Labath 
TEST(ArgsTest,TestArgv)114145d95c9SPavel Labath TEST(ArgsTest, TestArgv) {
115145d95c9SPavel Labath   Args args;
116145d95c9SPavel Labath   EXPECT_EQ(nullptr, args.GetArgumentVector());
117145d95c9SPavel Labath 
118145d95c9SPavel Labath   args.AppendArgument("1");
119145d95c9SPavel Labath   EXPECT_NE(nullptr, args.GetArgumentVector()[0]);
120145d95c9SPavel Labath   EXPECT_EQ(nullptr, args.GetArgumentVector()[1]);
121145d95c9SPavel Labath 
122145d95c9SPavel Labath   args.AppendArgument("2");
123145d95c9SPavel Labath   EXPECT_NE(nullptr, args.GetArgumentVector()[0]);
124145d95c9SPavel Labath   EXPECT_NE(nullptr, args.GetArgumentVector()[1]);
125145d95c9SPavel Labath   EXPECT_EQ(nullptr, args.GetArgumentVector()[2]);
126145d95c9SPavel Labath 
127145d95c9SPavel Labath   args.AppendArgument("3");
128145d95c9SPavel Labath   EXPECT_NE(nullptr, args.GetArgumentVector()[0]);
129145d95c9SPavel Labath   EXPECT_NE(nullptr, args.GetArgumentVector()[1]);
130145d95c9SPavel Labath   EXPECT_NE(nullptr, args.GetArgumentVector()[2]);
131145d95c9SPavel Labath   EXPECT_EQ(nullptr, args.GetArgumentVector()[3]);
132145d95c9SPavel Labath 
133145d95c9SPavel Labath   args.InsertArgumentAtIndex(1, "1.5");
134145d95c9SPavel Labath   EXPECT_NE(nullptr, args.GetArgumentVector()[0]);
135145d95c9SPavel Labath   EXPECT_NE(nullptr, args.GetArgumentVector()[1]);
136145d95c9SPavel Labath   EXPECT_NE(nullptr, args.GetArgumentVector()[2]);
137145d95c9SPavel Labath   EXPECT_NE(nullptr, args.GetArgumentVector()[3]);
138145d95c9SPavel Labath   EXPECT_EQ(nullptr, args.GetArgumentVector()[4]);
139145d95c9SPavel Labath 
140145d95c9SPavel Labath   args.InsertArgumentAtIndex(4, "3.5");
141145d95c9SPavel Labath   EXPECT_NE(nullptr, args.GetArgumentVector()[0]);
142145d95c9SPavel Labath   EXPECT_NE(nullptr, args.GetArgumentVector()[1]);
143145d95c9SPavel Labath   EXPECT_NE(nullptr, args.GetArgumentVector()[2]);
144145d95c9SPavel Labath   EXPECT_NE(nullptr, args.GetArgumentVector()[3]);
145145d95c9SPavel Labath   EXPECT_NE(nullptr, args.GetArgumentVector()[4]);
146145d95c9SPavel Labath   EXPECT_EQ(nullptr, args.GetArgumentVector()[5]);
147145d95c9SPavel Labath }
148145d95c9SPavel Labath 
TEST(ArgsTest,StringListConstructor)149145d95c9SPavel Labath TEST(ArgsTest, StringListConstructor) {
150145d95c9SPavel Labath   StringList list;
151145d95c9SPavel Labath   list << "foo"
152145d95c9SPavel Labath        << "bar"
153145d95c9SPavel Labath        << "baz";
154145d95c9SPavel Labath   Args args(list);
155145d95c9SPavel Labath   ASSERT_EQ(3u, args.GetArgumentCount());
1560d9a201eSRaphael Isemann   EXPECT_EQ("foo", args[0].ref());
1570d9a201eSRaphael Isemann   EXPECT_EQ("bar", args[1].ref());
1580d9a201eSRaphael Isemann   EXPECT_EQ("baz", args[2].ref());
159145d95c9SPavel Labath }
160145d95c9SPavel Labath 
TEST(ArgsTest,GetQuotedCommandString)161145d95c9SPavel Labath TEST(ArgsTest, GetQuotedCommandString) {
162145d95c9SPavel Labath   Args args;
163145d95c9SPavel Labath   const char *str = "process launch -o stdout.txt -- \"a b c\"";
164145d95c9SPavel Labath   args.SetCommandString(str);
165145d95c9SPavel Labath 
166145d95c9SPavel Labath   std::string stdstr;
167145d95c9SPavel Labath   ASSERT_TRUE(args.GetQuotedCommandString(stdstr));
168145d95c9SPavel Labath   EXPECT_EQ(str, stdstr);
169145d95c9SPavel Labath }
170145d95c9SPavel Labath 
TEST(ArgsTest,BareSingleQuote)171145d95c9SPavel Labath TEST(ArgsTest, BareSingleQuote) {
172145d95c9SPavel Labath   Args args;
173145d95c9SPavel Labath   args.SetCommandString("a\\'b");
174145d95c9SPavel Labath   EXPECT_EQ(1u, args.GetArgumentCount());
175145d95c9SPavel Labath 
176145d95c9SPavel Labath   EXPECT_STREQ("a'b", args.GetArgumentAtIndex(0));
177145d95c9SPavel Labath }
178145d95c9SPavel Labath 
TEST(ArgsTest,DoubleQuotedItem)179145d95c9SPavel Labath TEST(ArgsTest, DoubleQuotedItem) {
180145d95c9SPavel Labath   Args args;
181145d95c9SPavel Labath   args.SetCommandString("\"a b c\"");
182145d95c9SPavel Labath   EXPECT_EQ(1u, args.GetArgumentCount());
183145d95c9SPavel Labath 
184145d95c9SPavel Labath   EXPECT_STREQ("a b c", args.GetArgumentAtIndex(0));
185145d95c9SPavel Labath }
186145d95c9SPavel Labath 
TEST(ArgsTest,AppendArguments)187145d95c9SPavel Labath TEST(ArgsTest, AppendArguments) {
188145d95c9SPavel Labath   Args args;
189145d95c9SPavel Labath   const char *argv[] = {"1", "2", nullptr};
190145d95c9SPavel Labath   const char *argv2[] = {"3", "4", nullptr};
191145d95c9SPavel Labath 
192145d95c9SPavel Labath   args.AppendArguments(argv);
193145d95c9SPavel Labath   ASSERT_EQ(2u, args.GetArgumentCount());
194145d95c9SPavel Labath   EXPECT_STREQ("1", args.GetArgumentVector()[0]);
195145d95c9SPavel Labath   EXPECT_STREQ("2", args.GetArgumentVector()[1]);
196145d95c9SPavel Labath   EXPECT_EQ(nullptr, args.GetArgumentVector()[2]);
197145d95c9SPavel Labath   EXPECT_STREQ("1", args.GetArgumentAtIndex(0));
198145d95c9SPavel Labath   EXPECT_STREQ("2", args.GetArgumentAtIndex(1));
199145d95c9SPavel Labath 
200145d95c9SPavel Labath   args.AppendArguments(argv2);
201145d95c9SPavel Labath   ASSERT_EQ(4u, args.GetArgumentCount());
202145d95c9SPavel Labath   EXPECT_STREQ("1", args.GetArgumentVector()[0]);
203145d95c9SPavel Labath   EXPECT_STREQ("2", args.GetArgumentVector()[1]);
204145d95c9SPavel Labath   EXPECT_STREQ("3", args.GetArgumentVector()[2]);
205145d95c9SPavel Labath   EXPECT_STREQ("4", args.GetArgumentVector()[3]);
206145d95c9SPavel Labath   EXPECT_EQ(nullptr, args.GetArgumentVector()[4]);
207145d95c9SPavel Labath   EXPECT_STREQ("1", args.GetArgumentAtIndex(0));
208145d95c9SPavel Labath   EXPECT_STREQ("2", args.GetArgumentAtIndex(1));
209145d95c9SPavel Labath   EXPECT_STREQ("3", args.GetArgumentAtIndex(2));
210145d95c9SPavel Labath   EXPECT_STREQ("4", args.GetArgumentAtIndex(3));
211145d95c9SPavel Labath }
212145d95c9SPavel Labath 
TEST(ArgsTest,GetArgumentArrayRef)213145d95c9SPavel Labath TEST(ArgsTest, GetArgumentArrayRef) {
214145d95c9SPavel Labath   Args args("foo bar");
215145d95c9SPavel Labath   auto ref = args.GetArgumentArrayRef();
216145d95c9SPavel Labath   ASSERT_EQ(2u, ref.size());
217145d95c9SPavel Labath   EXPECT_STREQ("foo", ref[0]);
218145d95c9SPavel Labath   EXPECT_STREQ("bar", ref[1]);
219145d95c9SPavel Labath }
2207d3225c4SJonas Devlieghere 
TEST(ArgsTest,EscapeLLDBCommandArgument)2217d3225c4SJonas Devlieghere TEST(ArgsTest, EscapeLLDBCommandArgument) {
2227d3225c4SJonas Devlieghere   const std::string foo = "foo'";
2237d3225c4SJonas Devlieghere   EXPECT_EQ("foo\\'", Args::EscapeLLDBCommandArgument(foo, '\0'));
2247d3225c4SJonas Devlieghere   EXPECT_EQ("foo'", Args::EscapeLLDBCommandArgument(foo, '\''));
2257d3225c4SJonas Devlieghere   EXPECT_EQ("foo'", Args::EscapeLLDBCommandArgument(foo, '`'));
2267d3225c4SJonas Devlieghere   EXPECT_EQ("foo'", Args::EscapeLLDBCommandArgument(foo, '"'));
2277d3225c4SJonas Devlieghere 
2287d3225c4SJonas Devlieghere   const std::string bar = "bar\"";
2297d3225c4SJonas Devlieghere   EXPECT_EQ("bar\\\"", Args::EscapeLLDBCommandArgument(bar, '\0'));
2307d3225c4SJonas Devlieghere   EXPECT_EQ("bar\"", Args::EscapeLLDBCommandArgument(bar, '\''));
2317d3225c4SJonas Devlieghere   EXPECT_EQ("bar\"", Args::EscapeLLDBCommandArgument(bar, '`'));
2327d3225c4SJonas Devlieghere   EXPECT_EQ("bar\\\"", Args::EscapeLLDBCommandArgument(bar, '"'));
2337d3225c4SJonas Devlieghere 
2347d3225c4SJonas Devlieghere   const std::string baz = "baz`";
2357d3225c4SJonas Devlieghere   EXPECT_EQ("baz\\`", Args::EscapeLLDBCommandArgument(baz, '\0'));
2367d3225c4SJonas Devlieghere   EXPECT_EQ("baz`", Args::EscapeLLDBCommandArgument(baz, '\''));
2377d3225c4SJonas Devlieghere   EXPECT_EQ("baz`", Args::EscapeLLDBCommandArgument(baz, '`'));
2387d3225c4SJonas Devlieghere   EXPECT_EQ("baz\\`", Args::EscapeLLDBCommandArgument(baz, '"'));
2397d3225c4SJonas Devlieghere 
2407d3225c4SJonas Devlieghere   const std::string quux = "quux\t";
2417d3225c4SJonas Devlieghere   EXPECT_EQ("quux\\\t", Args::EscapeLLDBCommandArgument(quux, '\0'));
2427d3225c4SJonas Devlieghere   EXPECT_EQ("quux\t", Args::EscapeLLDBCommandArgument(quux, '\''));
2437d3225c4SJonas Devlieghere   EXPECT_EQ("quux\t", Args::EscapeLLDBCommandArgument(quux, '`'));
2447d3225c4SJonas Devlieghere   EXPECT_EQ("quux\t", Args::EscapeLLDBCommandArgument(quux, '"'));
2457d3225c4SJonas Devlieghere }
2460d50c4e0SRaphael Isemann 
TEST(ArgsTest,ReplaceArgumentAtIndexShort)2470d50c4e0SRaphael Isemann TEST(ArgsTest, ReplaceArgumentAtIndexShort) {
2480d50c4e0SRaphael Isemann   Args args;
2490d50c4e0SRaphael Isemann   args.SetCommandString("foo ba b");
2500d50c4e0SRaphael Isemann   args.ReplaceArgumentAtIndex(0, "f");
2510d50c4e0SRaphael Isemann   EXPECT_EQ(3u, args.GetArgumentCount());
2520d50c4e0SRaphael Isemann   EXPECT_STREQ(args.GetArgumentAtIndex(0), "f");
2530d50c4e0SRaphael Isemann }
2540d50c4e0SRaphael Isemann 
TEST(ArgsTest,ReplaceArgumentAtIndexEqual)2550d50c4e0SRaphael Isemann TEST(ArgsTest, ReplaceArgumentAtIndexEqual) {
2560d50c4e0SRaphael Isemann   Args args;
2570d50c4e0SRaphael Isemann   args.SetCommandString("foo ba b");
2580d50c4e0SRaphael Isemann   args.ReplaceArgumentAtIndex(0, "bar");
2590d50c4e0SRaphael Isemann   EXPECT_EQ(3u, args.GetArgumentCount());
2600d50c4e0SRaphael Isemann   EXPECT_STREQ(args.GetArgumentAtIndex(0), "bar");
2610d50c4e0SRaphael Isemann }
2620d50c4e0SRaphael Isemann 
TEST(ArgsTest,ReplaceArgumentAtIndexLonger)2630d50c4e0SRaphael Isemann TEST(ArgsTest, ReplaceArgumentAtIndexLonger) {
2640d50c4e0SRaphael Isemann   Args args;
2650d50c4e0SRaphael Isemann   args.SetCommandString("foo ba b");
2660d50c4e0SRaphael Isemann   args.ReplaceArgumentAtIndex(0, "baar");
2670d50c4e0SRaphael Isemann   EXPECT_EQ(3u, args.GetArgumentCount());
2680d50c4e0SRaphael Isemann   EXPECT_STREQ(args.GetArgumentAtIndex(0), "baar");
2690d50c4e0SRaphael Isemann }
2700d50c4e0SRaphael Isemann 
TEST(ArgsTest,ReplaceArgumentAtIndexOutOfRange)2710d50c4e0SRaphael Isemann TEST(ArgsTest, ReplaceArgumentAtIndexOutOfRange) {
2720d50c4e0SRaphael Isemann   Args args;
2730d50c4e0SRaphael Isemann   args.SetCommandString("foo ba b");
2740d50c4e0SRaphael Isemann   args.ReplaceArgumentAtIndex(3, "baar");
2750d50c4e0SRaphael Isemann   EXPECT_EQ(3u, args.GetArgumentCount());
2760d50c4e0SRaphael Isemann   EXPECT_STREQ(args.GetArgumentAtIndex(2), "b");
2770d50c4e0SRaphael Isemann }
2780d50c4e0SRaphael Isemann 
TEST(ArgsTest,ReplaceArgumentAtIndexFarOutOfRange)2790d50c4e0SRaphael Isemann TEST(ArgsTest, ReplaceArgumentAtIndexFarOutOfRange) {
2800d50c4e0SRaphael Isemann   Args args;
2810d50c4e0SRaphael Isemann   args.SetCommandString("foo ba b");
2820d50c4e0SRaphael Isemann   args.ReplaceArgumentAtIndex(4, "baar");
2830d50c4e0SRaphael Isemann   EXPECT_EQ(3u, args.GetArgumentCount());
2840d50c4e0SRaphael Isemann   EXPECT_STREQ(args.GetArgumentAtIndex(2), "b");
2850d50c4e0SRaphael Isemann }
286bad61548SJonas Devlieghere 
TEST(ArgsTest,GetShellSafeArgument)287bb1d702eSRaphael Isemann TEST(ArgsTest, GetShellSafeArgument) {
288bb1d702eSRaphael Isemann   // Try escaping with bash at start/middle/end of the argument.
289bb1d702eSRaphael Isemann   FileSpec bash("/bin/bash", FileSpec::Style::posix);
290bb1d702eSRaphael Isemann   EXPECT_EQ(Args::GetShellSafeArgument(bash, "\"b"), "\\\"b");
291bb1d702eSRaphael Isemann   EXPECT_EQ(Args::GetShellSafeArgument(bash, "a\""), "a\\\"");
292bb1d702eSRaphael Isemann   EXPECT_EQ(Args::GetShellSafeArgument(bash, "a\"b"), "a\\\"b");
293bb1d702eSRaphael Isemann 
294c197cddbSRaphael Isemann   FileSpec zsh("/bin/zsh", FileSpec::Style::posix);
295c197cddbSRaphael Isemann   EXPECT_EQ(Args::GetShellSafeArgument(zsh, R"('";()<>&|\)"),
296c197cddbSRaphael Isemann             R"(\'\"\;\(\)\<\>\&\|\\)");
297c197cddbSRaphael Isemann   // Normal characters and expressions that shouldn't be escaped.
298c197cddbSRaphael Isemann   EXPECT_EQ(Args::GetShellSafeArgument(zsh, "aA$1*"), "aA$1*");
299c197cddbSRaphael Isemann 
30007a722c5SRaphael Isemann   // Test escaping bash special characters.
30107a722c5SRaphael Isemann   EXPECT_EQ(Args::GetShellSafeArgument(bash, R"( '"<>()&;)"),
30207a722c5SRaphael Isemann             R"(\ \'\"\<\>\(\)\&\;)");
30307a722c5SRaphael Isemann   // Normal characters and globbing expressions that shouldn't be escaped.
30407a722c5SRaphael Isemann   EXPECT_EQ(Args::GetShellSafeArgument(bash, "aA$1*"), "aA$1*");
305bb1d702eSRaphael Isemann 
30607a722c5SRaphael Isemann   // Test escaping tcsh special characters.
307bb1d702eSRaphael Isemann   FileSpec tcsh("/bin/tcsh", FileSpec::Style::posix);
308acc56e55SJonas Devlieghere   EXPECT_EQ(Args::GetShellSafeArgument(tcsh, R"( '"<>()&;)"),
309acc56e55SJonas Devlieghere             R"(\ \'\"\<\>\(\)\&\;)");
31007a722c5SRaphael Isemann   // Normal characters and globbing expressions that shouldn't be escaped.
31107a722c5SRaphael Isemann   EXPECT_EQ(Args::GetShellSafeArgument(tcsh, "aA1*"), "aA1*");
31207a722c5SRaphael Isemann 
31307a722c5SRaphael Isemann   // Test escaping sh special characters.
31407a722c5SRaphael Isemann   FileSpec sh("/bin/sh", FileSpec::Style::posix);
31507a722c5SRaphael Isemann   EXPECT_EQ(Args::GetShellSafeArgument(sh, R"( '"<>()&;)"),
31607a722c5SRaphael Isemann             R"(\ \'\"\<\>\(\)\&\;)");
31707a722c5SRaphael Isemann   // Normal characters and globbing expressions that shouldn't be escaped.
31807a722c5SRaphael Isemann   EXPECT_EQ(Args::GetShellSafeArgument(sh, "aA$1*"), "aA$1*");
319bb1d702eSRaphael Isemann 
320*9bc34636SRaphael Isemann   // Test escaping fish special characters.
321*9bc34636SRaphael Isemann   FileSpec fish("/bin/fish", FileSpec::Style::posix);
322*9bc34636SRaphael Isemann   EXPECT_EQ(Args::GetShellSafeArgument(fish, R"( '"<>()&\|;)"),
323*9bc34636SRaphael Isemann             R"(\ \'\"\<\>\(\)\&\\\|\;)");
324*9bc34636SRaphael Isemann   // Normal characters and expressions that shouldn't be escaped.
325*9bc34636SRaphael Isemann   EXPECT_EQ(Args::GetShellSafeArgument(fish, "aA$1*"), "aA$1*");
326*9bc34636SRaphael Isemann 
327bb1d702eSRaphael Isemann   // Try escaping with an unknown shell.
328bb1d702eSRaphael Isemann   FileSpec unknown_shell("/bin/unknown_shell", FileSpec::Style::posix);
329bb1d702eSRaphael Isemann   EXPECT_EQ(Args::GetShellSafeArgument(unknown_shell, "a'b"), "a\\'b");
330bb1d702eSRaphael Isemann   EXPECT_EQ(Args::GetShellSafeArgument(unknown_shell, "a\"b"), "a\\\"b");
331bb1d702eSRaphael Isemann }
332