mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-04-19 05:50:27 +00:00
macos: quote input strings used for shell commands
When we're building an input string that's explicitly meant to be used as a shell command, quote (escape) it using the same logic as Python's shlex.quote function. This specifically addresses issues we've seen when open(1)'ing Ghostty with filename arguments that contain spaces.
This commit is contained in:
@@ -476,7 +476,7 @@ class AppDelegate: NSObject,
|
||||
// profile/rc files for the shell, which is super important on macOS
|
||||
// due to things like Homebrew. Instead, we set the command to
|
||||
// `<filename>; exit` which is what Terminal and iTerm2 do.
|
||||
config.initialInput = "\(filename); exit\n"
|
||||
config.initialInput = "\(filename.shellQuoted()); exit\n"
|
||||
|
||||
// For commands executed directly, we want to ensure we wait after exit
|
||||
// because in most cases scripts don't block on exit and we don't want
|
||||
|
||||
@@ -68,7 +68,7 @@ struct NewTerminalIntent: AppIntent {
|
||||
// We don't run command as "command" and instead use "initialInput" so
|
||||
// that we can get all the login scripts to setup things like PATH.
|
||||
if let command {
|
||||
config.initialInput = "\(command); exit\n"
|
||||
config.initialInput = "\(command.shellQuoted()); exit\n"
|
||||
}
|
||||
|
||||
// If we were given a working directory then open that directory
|
||||
|
||||
@@ -26,4 +26,12 @@ extension String {
|
||||
return self
|
||||
}
|
||||
#endif
|
||||
|
||||
private static let shellUnsafe = /[^\w@%+=:,.\/-]/
|
||||
|
||||
/// Returns a shell-escaped version of the string, like Python's shlex.quote.
|
||||
func shellQuoted() -> String {
|
||||
guard self.isEmpty || self.contains(Self.shellUnsafe) else { return self };
|
||||
return "'" + self.replacingOccurrences(of: "'", with: #"'"'"'"#) + "'"
|
||||
}
|
||||
}
|
||||
|
||||
19
macos/Tests/Helpers/Extensions/StringExtensionTests.swift
Normal file
19
macos/Tests/Helpers/Extensions/StringExtensionTests.swift
Normal file
@@ -0,0 +1,19 @@
|
||||
import Testing
|
||||
@testable import Ghostty
|
||||
|
||||
struct StringExtensionTests {
|
||||
@Test(arguments: [
|
||||
("", "''"),
|
||||
("filename", "filename"),
|
||||
("abcABC123@%_-+=:,./", "abcABC123@%_-+=:,./"),
|
||||
("file name", "'file name'"),
|
||||
("file$name", "'file$name'"),
|
||||
("file!name", "'file!name'"),
|
||||
("file\\name", "'file\\name'"),
|
||||
("it's", "'it'\"'\"'s'"),
|
||||
("file$'name'", "'file$'\"'\"'name'\"'\"''"),
|
||||
])
|
||||
func shellQuoted(input: String, expected: String) {
|
||||
#expect(input.shellQuoted() == expected)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user