diff options
-rw-r--r-- | lldb/include/lldb/API/SBLaunchInfo.h | 2 | ||||
-rw-r--r-- | lldb/include/lldb/Interpreter/Args.h | 2 | ||||
-rw-r--r-- | lldb/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/TestLaunchWithShellExpand.py | 6 | ||||
-rw-r--r-- | lldb/source/Interpreter/Args.cpp | 34 | ||||
-rw-r--r-- | lldb/source/Target/Platform.cpp | 4 | ||||
-rw-r--r-- | lldb/source/Target/ProcessLaunchInfo.cpp | 4 |
6 files changed, 45 insertions, 7 deletions
diff --git a/lldb/include/lldb/API/SBLaunchInfo.h b/lldb/include/lldb/API/SBLaunchInfo.h index 68c0f386acd..38d598aec45 100644 --- a/lldb/include/lldb/API/SBLaunchInfo.h +++ b/lldb/include/lldb/API/SBLaunchInfo.h @@ -145,7 +145,7 @@ public: GetShellExpandArguments (); void - SetShellExpandArguments (bool glob); + SetShellExpandArguments (bool expand); uint32_t GetResumeCount (); diff --git a/lldb/include/lldb/Interpreter/Args.h b/lldb/include/lldb/Interpreter/Args.h index e79318ba562..c55b2f63173 100644 --- a/lldb/include/lldb/Interpreter/Args.h +++ b/lldb/include/lldb/Interpreter/Args.h @@ -403,7 +403,7 @@ public: StringToVersion (const char *s, uint32_t &major, uint32_t &minor, uint32_t &update); static const char * - GetShellSafeArgument (const char *unsafe_arg, std::string &safe_arg); + GetShellSafeArgument (const FileSpec& shell, const char *unsafe_arg, std::string &safe_arg); // EncodeEscapeSequences will change the textual representation of common // escape sequences like "\n" (two characters) into a single '\n'. It does diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/TestLaunchWithShellExpand.py b/lldb/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/TestLaunchWithShellExpand.py index fa90d79b82d..28d8cccacfc 100644 --- a/lldb/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/TestLaunchWithShellExpand.py +++ b/lldb/packages/Python/lldbsuite/test/functionalities/launch_with_shellexpand/TestLaunchWithShellExpand.py @@ -30,7 +30,7 @@ class LaunchWithShellExpandTestCase(TestBase): breakpoint = target.BreakpointCreateBySourceRegex ('break here', lldb.SBFileSpec ("main.cpp", False)) self.assertTrue(breakpoint, VALID_BREAKPOINT) - self.runCmd("process launch -X true -w %s -- fi*.tx?" % (os.getcwd())) + self.runCmd("process launch -X true -w %s -- fi*.tx? () > <" % (os.getcwd())) process = self.process() @@ -51,7 +51,11 @@ class LaunchWithShellExpandTestCase(TestBase): self.expect("frame variable argv[2]", substrs=['file2.txt']) self.expect("frame variable argv[3]", substrs=['file3.txt']) self.expect("frame variable argv[4]", substrs=['file4.txy']) + self.expect("frame variable argv[5]", substrs=['()']) + self.expect("frame variable argv[6]", substrs=['>']) + self.expect("frame variable argv[7]", substrs=['<']) self.expect("frame variable argv[5]", substrs=['file5.tyx'], matching=False) + self.expect("frame variable argv[8]", substrs=['file5.tyx'], matching=False) self.runCmd("process kill") diff --git a/lldb/source/Interpreter/Args.cpp b/lldb/source/Interpreter/Args.cpp index 81e6b0aa1db..f6c018f4262 100644 --- a/lldb/source/Interpreter/Args.cpp +++ b/lldb/source/Interpreter/Args.cpp @@ -887,14 +887,43 @@ Args::StringToVersion (const char *s, uint32_t &major, uint32_t &minor, uint32_t } const char * -Args::GetShellSafeArgument (const char *unsafe_arg, std::string &safe_arg) +Args::GetShellSafeArgument (const FileSpec& shell, + const char *unsafe_arg, + std::string &safe_arg) { + struct ShellDescriptor + { + ConstString m_basename; + const char* m_escapables; + }; + + static ShellDescriptor g_Shells[] = { + {ConstString("bash")," '\"<>()&"}, + {ConstString("tcsh")," '\"<>()&$"}, + {ConstString("sh")," '\"<>()&"} + }; + + // safe minimal set + const char* escapables = " '\""; + + if (auto basename = shell.GetFilename()) + { + for (const auto& Shell : g_Shells) + { + if (Shell.m_basename == basename) + { + escapables = Shell.m_escapables; + break; + } + } + } + safe_arg.assign (unsafe_arg); size_t prev_pos = 0; while (prev_pos < safe_arg.size()) { // Escape spaces and quotes - size_t pos = safe_arg.find_first_of(" '\"", prev_pos); + size_t pos = safe_arg.find_first_of(escapables, prev_pos); if (pos != std::string::npos) { safe_arg.insert (pos, 1, '\\'); @@ -906,7 +935,6 @@ Args::GetShellSafeArgument (const char *unsafe_arg, std::string &safe_arg) return safe_arg.c_str(); } - int64_t Args::StringToOptionEnum (const char *s, OptionEnumValueElement *enum_values, int32_t fail_value, Error &error) { diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp index 436a710982f..72db562aabc 100644 --- a/lldb/source/Target/Platform.cpp +++ b/lldb/source/Target/Platform.cpp @@ -1241,7 +1241,11 @@ Platform::LaunchProcess (ProcessLaunchInfo &launch_info) { error = ShellExpandArguments(launch_info); if (error.Fail()) + { + error.SetErrorStringWithFormat("shell expansion failed (reason: %s). consider launching with 'process launch'.", + error.AsCString("unknown")); return error; + } } if (log) diff --git a/lldb/source/Target/ProcessLaunchInfo.cpp b/lldb/source/Target/ProcessLaunchInfo.cpp index 4e4db8742e5..58e42e7caa1 100644 --- a/lldb/source/Target/ProcessLaunchInfo.cpp +++ b/lldb/source/Target/ProcessLaunchInfo.cpp @@ -503,7 +503,9 @@ ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell (Error &error, { for (size_t i=0; argv[i] != nullptr; ++i) { - const char *arg = Args::GetShellSafeArgument (argv[i], safe_arg); + const char *arg = Args::GetShellSafeArgument (m_shell, + argv[i], + safe_arg); shell_command.Printf(" %s", arg); } } |