Skip to content

fix(runner): split comma-separated targets from -l file and stdin (#859)#953

Open
TheAuroraAI wants to merge 2 commits intoprojectdiscovery:mainfrom
TheAuroraAI:fix/list-comma-separated-targets-859
Open

fix(runner): split comma-separated targets from -l file and stdin (#859)#953
TheAuroraAI wants to merge 2 commits intoprojectdiscovery:mainfrom
TheAuroraAI:fix/list-comma-separated-targets-859

Conversation

@TheAuroraAI
Copy link

@TheAuroraAI TheAuroraAI commented Mar 10, 2026

Summary

The -u flag accepts comma-separated hosts natively via goflags.CommaSeparatedStringSliceOptions. The -l file path (and stdin) did not: every raw line was handed directly to processInputItem, so a file containing 192.168.1.0/24,192.168.2.0/24 was treated as a single, invalid host:

[WRN] Could not connect input 192.168.1.0/24,192.168.2.0/24:443
      [auto,ztls:RUNTIME] failed to setup connection
      <- could not dial address <- no address found for host

Fixes #859.

Root cause

normalizeAndQueueInputs reads the file (and stdin) line-by-line and calls processInputItem(text, inputs) on the full raw line. There was no splitting step.

The -u path goes through goflags.CommaSeparatedStringSliceOptions which splits at flag-parse time, so the runner never sees the commas.

Fix

After reading each line from the file / stdin, split on , and trim whitespace before forwarding to processInputItem. This makes the two input methods behave identically.

// Before
r.processInputItem(text, inputs)

// After
for _, item := range strings.Split(text, ",") {
    if item = strings.TrimSpace(item); item != "" {
        r.processInputItem(item, inputs)
    }
}

The same fix is applied to both the file path and the stdin path.

Test

Added Test_CommaSeperatedInputList_normalizeAndQueueInputs which writes a temporary file with a single comma-separated line, runs normalizeAndQueueInputs, and asserts that both hosts are queued individually.

go test ./internal/runner/... -run Test_CommaSeperatedInputList
ok  github.com/projectdiscovery/tlsx/internal/runner 0.129s

Summary by CodeRabbit

  • New Features

    • Accept comma-separated targets on a single line from input files and stdin; each entry is trimmed and queued as an individual target.
  • Tests

    • Added automated test coverage validating splitting and queuing of comma-separated inputs.

…ojectdiscovery#859)

The -u flag accepts comma-separated hosts via CommaSeparatedStringSliceOptions,
but the file-based -l (and stdin) path fed each raw line to processInputItem
as a single string. A line like '192.168.1.0/24,192.168.2.0/24' was treated
as one invalid host, producing:

  [WRN] Could not connect input 192.168.1.0/24,192.168.2.0/24:443 ...
        could not dial address <- no address found for host

Fix: when reading lines from the input file or stdin, split each line on
commas and trim whitespace before forwarding to processInputItem, so that
the two input methods behave identically.

A new table-driven unit test verifies that both entries are queued when
the input file contains a comma-separated line.

Fixes projectdiscovery#859.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@neo-by-projectdiscovery-dev
Copy link

neo-by-projectdiscovery-dev bot commented Mar 10, 2026

Neo - PR Security Review

No security issues found

Highlights

  • Adds comma-separated input parsing for -l file and stdin to match -u flag behavior
  • New helper function processCommaSeparatedTargets splits lines on commas and trims whitespace before processing
  • Includes test coverage for the new comma-separated input behavior
Hardening Notes
  • The comma-splitting logic is safe: uses standard strings.Split and strings.TrimSpace operations
  • User input flows through net.JoinHostPort (safe network address formatting) and eventually to TLS connection libraries
  • When openssl mode is used, exec.CommandContext with separate args array prevents command injection (no shell invocation)
  • This change provides feature parity between file/stdin input and command-line flag input

Comment @pdneo help for available commands. · Open in Neo

@coderabbitai
Copy link

coderabbitai bot commented Mar 10, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e8b7a091-42e9-4c2b-85d6-a8d99ef17111

📥 Commits

Reviewing files that changed from the base of the PR and between 8a6f015 and 6af7c6c.

📒 Files selected for processing (2)
  • internal/runner/runner.go
  • internal/runner/runner_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/runner/runner.go

Walkthrough

The runner now splits comma-separated targets on each input line (from files and STDIN), trims whitespace, filters empties, and queues each item individually via a new helper, instead of treating the whole line as one input. Control flow and error handling otherwise unchanged.

Changes

Cohort / File(s) Summary
Input Normalization Enhancement
internal/runner/runner.go
Added processCommaSeparatedTargets(text string, inputs chan taskInput) and updated normalizeAndQueueInputs to split lines by commas, trim entries, filter empties, and call processInputItem for each target.
Test Coverage
internal/runner/runner_test.go
Added Test_CommaSeparatedInputList_normalizeAndQueueInputs to verify comma-separated targets in a single-line input file are split and queued individually.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 I nibble commas, one by one,
Each host freed to hop and run,
From single line to many more,
Queued and trimmed, I clap—encore! 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(runner): split comma-separated targets from -l file and stdin (#859)' clearly and specifically describes the main change—enabling comma-separated target parsing in file/stdin inputs, matching the primary objective of the PR.
Linked Issues check ✅ Passed The PR fully addresses issue #859 by implementing comma-separated target splitting in both -l file and stdin input paths, achieving parity with the -u flag behavior and allowing lines like 'prefix1,prefix2,prefix3' to be processed as individual targets.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing issue #859: the new processCommaSeparatedTargets helper, updates to normalizeAndQueueInputs, and the test validating comma-separated input splitting. No extraneous modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
internal/runner/runner.go (1)

443-448: Consider extracting duplicated comma-split logic into a helper.

The same splitting logic appears in both the file and stdin paths. Extracting it improves maintainability.

♻️ Suggested helper extraction
+// processLineWithCommaSeparatedTargets splits a line by comma and queues each non-empty item.
+func (r *Runner) processLineWithCommaSeparatedTargets(text string, inputs chan taskInput) {
+	for _, item := range strings.Split(text, ",") {
+		if item = strings.TrimSpace(item); item != "" {
+			r.processInputItem(item, inputs)
+		}
+	}
+}

Then replace both occurrences:

 		if text != "" {
-			// Support comma-separated targets on a single line, matching the -u flag behaviour.
-			for _, item := range strings.Split(text, ",") {
-				if item = strings.TrimSpace(item); item != "" {
-					r.processInputItem(item, inputs)
-				}
-			}
+			r.processLineWithCommaSeparatedTargets(text, inputs)
 		}

Also applies to: 457-462

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/runner/runner.go` around lines 443 - 448, Duplicate comma-splitting
+ trimming logic should be extracted into a small helper method on the runner
(e.g., r.splitAndProcessInput or r.processCommaSeparatedInputs) that takes the
raw text and the inputs collection, performs strings.Split(text, ","), trims
each item, skips empties, and calls r.processInputItem(item, inputs) for each;
replace both occurrences (the file path handling and the stdin handling) with
calls to this new helper so the behavior is identical and maintenance is
centralized.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@internal/runner/runner_test.go`:
- Around line 433-436: Rename the test function
Test_CommaSeperatedInputList_normalizeAndQueueInputs to
Test_CommaSeparatedInputList_normalizeAndQueueInputs and update the leading
comment text to use "Separated" instead of "Seperated" so both the function name
and its comment read "Separated" (ensure you update every occurrence, including
the test declaration and the comment that begins "//
Test_CommaSeperatedInputList_normalizeAndQueueInputs ...").

---

Nitpick comments:
In `@internal/runner/runner.go`:
- Around line 443-448: Duplicate comma-splitting + trimming logic should be
extracted into a small helper method on the runner (e.g., r.splitAndProcessInput
or r.processCommaSeparatedInputs) that takes the raw text and the inputs
collection, performs strings.Split(text, ","), trims each item, skips empties,
and calls r.processInputItem(item, inputs) for each; replace both occurrences
(the file path handling and the stdin handling) with calls to this new helper so
the behavior is identical and maintenance is centralized.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a184f78e-9e53-46d6-bb21-f499b77b6fcb

📥 Commits

Reviewing files that changed from the base of the PR and between d13b67f and 8a6f015.

📒 Files selected for processing (2)
  • internal/runner/runner.go
  • internal/runner/runner_test.go

- Rename Test_CommaSeperatedInputList → Test_CommaSeparatedInputList (typo fix)
- Extract processCommaSeparatedTargets helper to deduplicate comma-split logic
  from file and stdin reading paths
@TheAuroraAI
Copy link
Author

Hi @dogancanbakir — this PR adds comma-separated target support to the -l flag, matching the -u flag behavior. Neo security review shows no issues. Would appreciate a review!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

-l -list option does not understand multiple prefixes, comma-separated in a single line

1 participant