Rules-based browser launcher for TUI + GNOME. switchyard.aly.codes
tui gome bowser go
0

Configure Feed

Select the types of activity you want to include in your feed.

fix: properly quote urls for shells

Aly Raffauf (Jan 28, 2026, 5:21 PM EST) 9e242719 24a4af5f

+17 -6
+8 -6
src/launch.go
··· 19 19 strings.Contains(cmdline, "%f") || 20 20 strings.Contains(cmdline, "%F") 21 21 22 - // Replace %u, %U, %f, %F with URL 23 - cmdline = strings.ReplaceAll(cmdline, "%u", url) 24 - cmdline = strings.ReplaceAll(cmdline, "%U", url) 25 - cmdline = strings.ReplaceAll(cmdline, "%f", url) 26 - cmdline = strings.ReplaceAll(cmdline, "%F", url) 22 + quotedURL := shellQuoteURL(url) 23 + 24 + // Replace %u, %U, %f, %F with quoted URL 25 + cmdline = strings.ReplaceAll(cmdline, "%u", quotedURL) 26 + cmdline = strings.ReplaceAll(cmdline, "%U", quotedURL) 27 + cmdline = strings.ReplaceAll(cmdline, "%f", quotedURL) 28 + cmdline = strings.ReplaceAll(cmdline, "%F", quotedURL) 27 29 28 30 // Remove other field codes 29 31 for _, code := range []string{"%i", "%c", "%k"} { ··· 32 34 33 35 // Chromium-based desktop files are essentially broken, they include no logic for a URL to pass using typical means. In this case, we work around by appending our URL. 34 36 if !hasFieldCode && url != "" { 35 - cmdline = cmdline + " " + url 37 + cmdline = cmdline + " " + quotedURL 36 38 } 37 39 38 40 if strings.TrimSpace(cmdline) == "" {
+9
src/url.go
··· 21 21 } 22 22 23 23 func sanitizeURL(rawURL string) string { 24 + // Remove newlines and carriage returns (common when URLs are copied from formatted text) 25 + rawURL = strings.ReplaceAll(rawURL, "\n", "") 26 + rawURL = strings.ReplaceAll(rawURL, "\r", "") 24 27 rawURL = strings.TrimSpace(rawURL) 25 28 if rawURL == "" { 26 29 return "" ··· 49 52 default: 50 53 return "" 51 54 } 55 + } 56 + 57 + // shellQuoteURL returns a shell-safe quoted version of the URL. 58 + // This prevents shell metacharacters like & from being interpreted. 59 + func shellQuoteURL(s string) string { 60 + return "'" + strings.ReplaceAll(s, "'", "'\"'\"'") + "'" 52 61 } 53 62 54 63 func parseSwitchyardURL(rawURL string) (targetURL string, browserPrefs []string, err error) {