Avoid O(n^2) string concatenation in maskActionContents

- `masked +=` per token copied the whole prefix on every append
- ~1 MB POST to --listen blocked the server for ~30 s
- switch to strings.Builder

Reported by Zachariah Mithani (@zachariah-mithani, AploSec).
This commit is contained in:
Junegunn Choi committed 2026-10-22 08:24:40 +09:00
1 parent ac28b8c3ba
commit b412a45053
2 files changed
+8 -6

No files matched your search

+1
View File
@@ -28,6 +28,7 @@ CHANGELOG
- The completion integration now requires nushell 0.116.1 or above, where an interactive completer can take the terminal through the `@interactive` attribute (#4934) (@sim590)
- Fixed `--no-sort` being ignored in filter mode with `--sync`, `--tac`, or `--bench` (#4940) (@NavpreetSSidhu)
- Vim plugin: Fixed garbage text on screen in Neovim with `set title` when the fzf command contains ANSI escape sequences (#4941)
- Fixed O(n^2) action parsing in `--listen`. A single ~1 MB request could block the server for ~30 s (@zachariah-mithani, AploSec)
0.74.5
------
+7 -6
View File
@@ -1678,15 +1678,15 @@ func init() {
}
func maskActionContents(action string) string {
masked := ""
var sb strings.Builder
Loop:
for len(action) > 0 {
loc := argActionRegexp.FindStringIndex(action)
if loc == nil {
masked += action
sb.WriteString(action)
break
}
masked += action[:loc[1]]
sb.WriteString(action[:loc[1]])
action = action[loc[1]:]
if len(action) == 0 {
break
@@ -1695,7 +1695,7 @@ Loop:
var ce string
switch action[0] {
case ':':
masked += strings.Repeat(" ", len(action))
sb.WriteString(strings.Repeat(" ", len(action)))
break Loop
case '(':
ce = ")"
@@ -1716,7 +1716,7 @@ Loop:
// @$ or @+
loc = regexp.MustCompile(fmt.Sprintf(`(?s)^%s.*?(%s[+,]|%s$)`, cs, ce, ce)).FindStringIndex(action)
if loc == nil {
masked += action
sb.WriteString(action)
break
}
// Keep + or , at the end
@@ -1724,9 +1724,10 @@ Loop:
if lastChar == '+' || lastChar == ',' {
loc[1]--
}
masked += strings.Repeat(" ", loc[1])
sb.WriteString(strings.Repeat(" ", loc[1]))
action = action[loc[1]:]
}
masked := sb.String()
masked = strings.ReplaceAll(masked, ",,,", string([]rune{',', escapedComma, ','}))
masked = strings.ReplaceAll(masked, ",:,", string([]rune{',', escapedColon, ','}))
masked = strings.ReplaceAll(masked, "::", string([]rune{escapedColon, ':'}))