Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions internal/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -440,18 +440,24 @@ func (r *Runner) normalizeAndQueueInputs(inputs chan taskInput) error {
for scanner.Scan() {
text := scanner.Text()
if text != "" {
r.processInputItem(text, inputs)
r.processCommaSeparatedInput(text, inputs)
}
}
if err := scanner.Err(); err != nil {
return errkit.Wrap(err, "could not read input file")
}
}
if r.hasStdin {
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
text := scanner.Text()
if text != "" {
r.processInputItem(text, inputs)
r.processCommaSeparatedInput(text, inputs)
}
}
if err := scanner.Err(); err != nil {
return errkit.Wrap(err, "could not read stdin")
}
}
return nil
}
Expand Down Expand Up @@ -483,6 +489,25 @@ func (r *Runner) resolveFQDN(target string) ([]string, error) {
return hostIPs, nil
}

// processCommaSeparatedInput splits comma-separated input and processes each item individually.
// This handles the case where file (-l) or stdin input contains multiple targets on a single line.
func (r *Runner) processCommaSeparatedInput(input string, inputs chan taskInput) {
input = strings.TrimSpace(input)
if input == "" {
return
}
if strings.Contains(input, ",") {
for _, item := range strings.Split(input, ",") {
item = strings.TrimSpace(item)
if item != "" {
r.processInputItem(item, inputs)
}
}
return
}
r.processInputItem(input, inputs)
}

// processInputItem processes a single input item
func (r *Runner) processInputItem(input string, inputs chan taskInput) {
// AS Input
Expand Down
132 changes: 132 additions & 0 deletions internal/runner/runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,138 @@ func getTaskInputFromFile(filename string, ports []string) ([]taskInput, error)
return ret, nil
}

// Comma-separated input from file (-l) or stdin
func Test_CommaSeparatedInput_processCommaSeparatedInput(t *testing.T) {
options := &clients.Options{
Ports: []string{"443"},
}
runner := &Runner{options: options}

inputs := make(chan taskInput)
line := "www.example.com,scanme.sh,test.com"
expected := []taskInput{
{
host: "www.example.com",
port: "443",
},
{
host: "scanme.sh",
port: "443",
},
{
host: "test.com",
port: "443",
},
}
go func() {
defer close(inputs)
runner.processCommaSeparatedInput(line, inputs)
}()
var got []taskInput
for task := range inputs {
got = append(got, task)
}
require.ElementsMatch(t, expected, got, "could not get correct taskInputs")
}

// Comma-separated input with spaces around commas
func Test_CommaSeparatedInputWithSpaces_processCommaSeparatedInput(t *testing.T) {
options := &clients.Options{
Ports: []string{"443"},
}
runner := &Runner{options: options}

inputs := make(chan taskInput)
line := "www.example.com , scanme.sh , test.com"
expected := []taskInput{
{
host: "www.example.com",
port: "443",
},
{
host: "scanme.sh",
port: "443",
},
{
host: "test.com",
port: "443",
},
}
go func() {
defer close(inputs)
runner.processCommaSeparatedInput(line, inputs)
}()
var got []taskInput
for task := range inputs {
got = append(got, task)
}
require.ElementsMatch(t, expected, got, "could not get correct taskInputs")
}

// Single input (no commas) still works through processCommaSeparatedInput
func Test_SingleInput_processCommaSeparatedInput(t *testing.T) {
options := &clients.Options{
Ports: []string{"443"},
}
runner := &Runner{options: options}

inputs := make(chan taskInput)
line := "www.example.com"
expected := []taskInput{
{
host: "www.example.com",
port: "443",
},
}
go func() {
defer close(inputs)
runner.processCommaSeparatedInput(line, inputs)
}()
var got []taskInput
for task := range inputs {
got = append(got, task)
}
require.ElementsMatch(t, expected, got, "could not get correct taskInputs")
}

// Comma-separated with multiple ports
func Test_CommaSeparatedInputMultiplePorts_processCommaSeparatedInput(t *testing.T) {
options := &clients.Options{
Ports: []string{"443", "8443"},
}
runner := &Runner{options: options}

inputs := make(chan taskInput)
line := "www.example.com,scanme.sh"
expected := []taskInput{
{
host: "www.example.com",
port: "443",
},
{
host: "www.example.com",
port: "8443",
},
{
host: "scanme.sh",
port: "443",
},
{
host: "scanme.sh",
port: "8443",
},
}
go func() {
defer close(inputs)
runner.processCommaSeparatedInput(line, inputs)
}()
var got []taskInput
for task := range inputs {
got = append(got, task)
}
require.ElementsMatch(t, expected, got, "could not get correct taskInputs")
}

func Test_CTLogsModeValidation(t *testing.T) {
// Test that CT logs mode and input mode cannot be used together
// This validation is now done in the main package, so this test should be removed
Expand Down