mirror of
https://github.com/junegunn/fzf.git
synced 2026-10-28 08:05:53 +00:00
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:
2 files changed
+8
-6
No files matched your search
@@ -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)
|
- 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)
|
- 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)
|
- 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
|
0.74.5
|
||||||
------
|
------
|
||||||
|
|||||||
+7
-6
@@ -1678,15 +1678,15 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func maskActionContents(action string) string {
|
func maskActionContents(action string) string {
|
||||||
masked := ""
|
var sb strings.Builder
|
||||||
Loop:
|
Loop:
|
||||||
for len(action) > 0 {
|
for len(action) > 0 {
|
||||||
loc := argActionRegexp.FindStringIndex(action)
|
loc := argActionRegexp.FindStringIndex(action)
|
||||||
if loc == nil {
|
if loc == nil {
|
||||||
masked += action
|
sb.WriteString(action)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
masked += action[:loc[1]]
|
sb.WriteString(action[:loc[1]])
|
||||||
action = action[loc[1]:]
|
action = action[loc[1]:]
|
||||||
if len(action) == 0 {
|
if len(action) == 0 {
|
||||||
break
|
break
|
||||||
@@ -1695,7 +1695,7 @@ Loop:
|
|||||||
var ce string
|
var ce string
|
||||||
switch action[0] {
|
switch action[0] {
|
||||||
case ':':
|
case ':':
|
||||||
masked += strings.Repeat(" ", len(action))
|
sb.WriteString(strings.Repeat(" ", len(action)))
|
||||||
break Loop
|
break Loop
|
||||||
case '(':
|
case '(':
|
||||||
ce = ")"
|
ce = ")"
|
||||||
@@ -1716,7 +1716,7 @@ Loop:
|
|||||||
// @$ or @+
|
// @$ or @+
|
||||||
loc = regexp.MustCompile(fmt.Sprintf(`(?s)^%s.*?(%s[+,]|%s$)`, cs, ce, ce)).FindStringIndex(action)
|
loc = regexp.MustCompile(fmt.Sprintf(`(?s)^%s.*?(%s[+,]|%s$)`, cs, ce, ce)).FindStringIndex(action)
|
||||||
if loc == nil {
|
if loc == nil {
|
||||||
masked += action
|
sb.WriteString(action)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// Keep + or , at the end
|
// Keep + or , at the end
|
||||||
@@ -1724,9 +1724,10 @@ Loop:
|
|||||||
if lastChar == '+' || lastChar == ',' {
|
if lastChar == '+' || lastChar == ',' {
|
||||||
loc[1]--
|
loc[1]--
|
||||||
}
|
}
|
||||||
masked += strings.Repeat(" ", loc[1])
|
sb.WriteString(strings.Repeat(" ", loc[1]))
|
||||||
action = action[loc[1]:]
|
action = action[loc[1]:]
|
||||||
}
|
}
|
||||||
|
masked := sb.String()
|
||||||
masked = strings.ReplaceAll(masked, ",,,", string([]rune{',', escapedComma, ','}))
|
masked = strings.ReplaceAll(masked, ",,,", string([]rune{',', escapedComma, ','}))
|
||||||
masked = strings.ReplaceAll(masked, ",:,", string([]rune{',', escapedColon, ','}))
|
masked = strings.ReplaceAll(masked, ",:,", string([]rune{',', escapedColon, ','}))
|
||||||
masked = strings.ReplaceAll(masked, "::", string([]rune{escapedColon, ':'}))
|
masked = strings.ReplaceAll(masked, "::", string([]rune{escapedColon, ':'}))
|
||||||
|
|||||||
Reference in new issue
Block a user