on main help sign in
fix: address potential panic on shell command execution (#2200)
baedc28Andrey Nering
internal/shell/shell.go+13−4
@@ -259,20 +259,29 @@ func (s *Shell) updateShellFromRunner(runner *interp.Runner) {
259}
259}
260
260
261// execCommon is the shared implementation for executing commands
261// execCommon is the shared implementation for executing commands
262−func (s *Shell) execCommon(ctx context.Context, command string, stdout, stderr io.Writer) error {
262+func (s *Shell) execCommon(ctx context.Context, command string, stdout, stderr io.Writer) (err error) {
263+ var runner *interp.Runner
264+ defer func() {
265+ if r := recover(); r != nil {
266+ err = fmt.Errorf("command execution panic: %v", r)
267+ }
268+ if runner != nil {
269+ s.updateShellFromRunner(runner)
270+ }
271+ s.logger.InfoPersist("command finished", "command", command, "err", err)
272+ }()
273+
263 line, err := syntax.NewParser().Parse(strings.NewReader(command), "")
274 line, err := syntax.NewParser().Parse(strings.NewReader(command), "")
264 if err != nil {
275 if err != nil {
265 return fmt.Errorf("could not parse command: %w", err)
276 return fmt.Errorf("could not parse command: %w", err)
266 }
277 }
267
278
268− runner, err := s.newInterp(stdout, stderr)
279+ runner, err = s.newInterp(stdout, stderr)
269 if err != nil {
280 if err != nil {
270 return fmt.Errorf("could not run command: %w", err)
281 return fmt.Errorf("could not run command: %w", err)
271 }
282 }
272
283
273 err = runner.Run(ctx, line)
284 err = runner.Run(ctx, line)
274− s.updateShellFromRunner(runner)
275− s.logger.InfoPersist("command finished", "command", command, "err", err)
276 return err
285 return err
277}
286}
278
287