Skip to content

Commit

Permalink
fix running quoted commands with internal negate
Browse files Browse the repository at this point in the history
  • Loading branch information
sni committed Nov 25, 2024
1 parent 2072719 commit 0a2c546
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 1 deletion.
3 changes: 3 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
This file documents the revision history for the Mod-Gearman-Worker-Go

next:
- fix running quoted commands with internal negate

1.5.4 Fri Nov 22 14:09:37 CET 2024
- improve statistics log output

Expand Down
21 changes: 21 additions & 0 deletions pkg/modgearman/internal_negate.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"fmt"
"io"
"strings"

"github.com/sni/shelltoken"
)

// NegateDefaultTimeout sets the default timeout if negate is used
Expand Down Expand Up @@ -122,9 +124,28 @@ func ParseNegate(com *command) {

return
}

com.Command = com.Args[mainProgIndex]
com.Args = com.Args[mainProgIndex+1:]
com.Negate = negate

if len(com.Args) > 0 {
return
}

// recombine remaining program and args
remainingArgs := []string{}
_, subargs, suberr := shelltoken.SplitLinux(com.Command)
if suberr != nil {
log.Debugf("failed to parse shell args: %w: %s", suberr, suberr.Error())

return
}

remainingArgs = append(remainingArgs, subargs...)

com.Command = remainingArgs[0]
com.Args = remainingArgs[1:]
}

func (n *Negate) Apply(result *answer) {
Expand Down
48 changes: 47 additions & 1 deletion pkg/modgearman/internal_negate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,47 @@ import (
"github.com/stretchr/testify/assert"
)

func TestNegate(t *testing.T) {
func TestNegateParse(t *testing.T) {
cmdLine := "ENV1=test ./lib/negate -w OK -c UNKNOWN -s /bin/command comArg1 comArg2"
cmd := parseCommand(cmdLine, &config{internalNegate: true})

assert.Equal(t, Exec, cmd.ExecType, "exec type")
assert.NotNil(t, cmd.Negate, "parsed negate")
assert.Equal(t, map[string]string{"ENV1": "test"}, cmd.Env)
assert.Equal(t, "OK", cmd.Negate.WarningStatus, "parsed negate")
assert.Equal(t, "UNKNOWN", cmd.Negate.CriticalStatus, "parsed negate")
}

func TestNegateParseQuoted(t *testing.T) {
cmdLine := "./lib/negate \"/bin/bash comArg1 comArg2 ABC=123 -c 'te st'\""
cmd := parseCommand(cmdLine, &config{internalNegate: true})

assert.Equal(t, Exec, cmd.ExecType, "exec type")
assert.NotNil(t, cmd.Negate, "parsed negate")
assert.Equal(t, "/bin/bash", cmd.Command, "remaining parsed command")
assert.Equal(t, []string{"comArg1", "comArg2", "ABC=123", "-c", "te st"}, cmd.Args, "remaining args")
}

func TestNegateParseQuotedShell(t *testing.T) {
cmdLine := "lib/negate -t 1 -s /bin/sh -c 'sleep 3'"
cmd := parseCommand(cmdLine, &config{internalNegate: true})

assert.Equal(t, Exec, cmd.ExecType, "exec type")
assert.NotNil(t, cmd.Negate, "parsed negate")
assert.Equal(t, "/bin/sh", cmd.Command, "remaining parsed command")
assert.Equal(t, []string{"-c", "sleep 3"}, cmd.Args, "remaining args")
}

func TestNegateParseQuotedShellChars(t *testing.T) {
cmdLine := "lib/negate -t 1 -s /bin/sh -c 'sleep 3; echo $SHELL'"
cmd := parseCommand(cmdLine, &config{internalNegate: true})

assert.Equal(t, Exec, cmd.ExecType, "exec type")
assert.NotNil(t, cmd.Negate, "parsed negate")
assert.Equal(t, "/bin/sh", cmd.Command, "remaining parsed command")
assert.Equal(t, []string{"-c", "sleep 3; echo $SHELL"}, cmd.Args, "remaining args")
}

func TestExecuteCommandWithNegateI(t *testing.T) {
cfg := config{}
cfg.setDefaultValues()
Expand All @@ -31,6 +62,21 @@ func TestExecuteCommandWithNegateI(t *testing.T) {
assert.Equal(t, "WARNING - failed", result.output, "output replaced")
}

func TestExecuteCommandWithNegateII(t *testing.T) {
cfg := config{}
cfg.setDefaultValues()
cfg.encryption = false
result := &answer{}

executeCommandLine(result, &request{
commandLine: "lib/negate -o 1 \"/bin/sh -c 'echo OK'\"",
timeout: 10,
}, &cfg)
assert.Equal(t, "exec", result.execType, "exec type")
assert.Equal(t, 1, result.returnCode, "return code")
assert.Equal(t, "OK", result.output, "output replaced")
}

func TestExecuteCommandWithNegateNoOptions(t *testing.T) {
cfg := config{}
cfg.setDefaultValues()
Expand Down

0 comments on commit 0a2c546

Please sign in to comment.