Skip to content

Commit 9d5e295

Browse files
authored
Prevent REPL command dispatch loop (#3576)
* Prevent REPL command dispatch loop The problem: The interactive shell recursively invokes the root command for each line. The active command is stored in a private context value, so reusing the outer context without filtering makes the nested command inherit itself as its parent and causes command dispatch to loop indefinitely after input is submitted. The fix: This patch wraps the REPL dispatch context to hide active-command while preserving the application context. This avoids the infinite loop and allows command dispatch to execute normally. Signed-off-by: James Vasile <james@jamesvasile.com> * Add //nolint --------- Signed-off-by: James Vasile <james@jamesvasile.com>
1 parent 61e6a7b commit 9d5e295

1 file changed

Lines changed: 16 additions & 1 deletion

File tree

internal/action/repl.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ READ:
8686
default:
8787
}
8888

89-
if err := cmd.Root().Run(ctx, append([]string{"gopass"}, args...)); err != nil {
89+
if err := cmd.Root().Run(replContext{Context: ctx}, append([]string{"gopass"}, args...)); err != nil {
9090
continue
9191
}
9292
}
@@ -147,6 +147,21 @@ func unescapeEntry(s string) string {
147147
// completionSpec describes what candidates a command should complete against.
148148
type completionSpec int
149149

150+
// replContext filters out urfave/cli's private active-command value from a
151+
// nested command invocation. This prevents infinite loops as the nested
152+
// invocation would otherwise inherit the command currently being executed.
153+
type replContext struct {
154+
context.Context //nolint:containedctx
155+
}
156+
157+
func (c replContext) Value(key any) any {
158+
if fmt.Sprint(key) == "cli.context" {
159+
return nil
160+
}
161+
162+
return c.Context.Value(key)
163+
}
164+
150165
const (
151166
completeNone completionSpec = iota
152167
completeEntries // secret entries

0 commit comments

Comments
 (0)