Skip to content

Conversation

@oleveloper
Copy link

@oleveloper oleveloper commented Sep 1, 2025

Proposed changes

  • Add *types.Options field to ListInputProvider struct
  • Initialize options field in New() constructor
  • Enhance URL parsing error handling:
    • Change from debug messages to error messages
    • Distinguish single-target (-u) and batch (-l) modes
    • Single-target mode: exit immediately with os.Exit(1)
    • Batch mode: log error and skip invalid target
  • Apply consistent logic to both Set and Del functions

Fixes #6416

Fixes issue where:

  • Single-target mode with invalid hostname now exits immediately
  • Batch mode skips invalid hosts while continuing with valid ones
  • Duplicate error messages replaced with a single clear error message

Screenshot

  • Batch mode (-l option)

    • 스크린샷 2025-09-01 오후 6 37 50
  • Single target mode (-u option)

    • 스크린샷 2025-09-01 오후 6 37 07

Checklist

  • Pull request is created against the dev branch
  • All checks passed (lint, unit/integration/regression tests etc.) with my changes
  • I have added tests that prove my fix is effective or that my feature works
  • I have added necessary documentation (if appropriate)

Summary by CodeRabbit

  • Bug Fixes
    • Improved handling of invalid targets: single-target runs now show a clear message and exit; batch runs log a warning and skip invalid entries without stopping.
    • Enhanced deletion behavior when removing by IP to more reliably match the original input.
    • Switched to structured logging for URL/hostname validation errors, providing clearer diagnostics.

- Add *types.Options field to ListInputProvider struct
- Initialize options field in New() constructor
- Enhance URL parsing error handling:
  - Change from debug messages to error messages
  - Distinguish single-target (-u) and batch (-l) modes
  - Single-target mode: exit immediately with os.Exit(1)
  - Batch mode: log error and skip invalid target
- Apply consistent logic to both Set and Del functions

Fixes projectdiscovery#6416
@auto-assign auto-assign bot requested a review from dogancanbakir September 1, 2025 09:45
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 1, 2025

Walkthrough

Adds options to ListInputProvider, refactors error handling in Set/Del to branch on single-target vs batch mode, switches fmt errors to structured logging, adjusts deletion to use original input for IPs, and exits on invalid single-target inputs while skipping in batch mode.

Changes

Cohort / File(s) Summary
Input provider: options and control-flow
pkg/input/provider/list/hmap.go
- Added options *types.Options to ListInputProvider and wired via New(...)
- Replaced fmt errors with gologger logging in Set/Del
- Single-target vs batch behavior based on options.TargetsFilePath and options.Targets
- Single-target: log and os.Exit(1) on invalid target; Batch: warn and skip
- In Del, assign metaInput.Input = value for IP deletions
- Removed unused fmt import

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant User
  participant ListInputProvider as ListInputProvider
  participant Options as Options
  participant Logger as Logger
  participant OS as OS

  User->>ListInputProvider: Set(value)
  ListInputProvider->>ListInputProvider: parse URL / validate hostname
  alt invalid target
    ListInputProvider->>Options: check TargetsFilePath / Targets
    alt Single-target mode
      ListInputProvider->>Logger: info("invalid target ...")
      ListInputProvider->>OS: Exit(1)
    else Batch mode
      ListInputProvider->>Logger: warn("skipping invalid target ...")
      ListInputProvider-->>User: return (skip)
    end
  else valid target
    ListInputProvider-->>User: proceed (add)
  end
Loading
sequenceDiagram
  autonumber
  participant User
  participant ListInputProvider as ListInputProvider
  participant Options as Options
  participant Logger as Logger
  participant OS as OS

  User->>ListInputProvider: Del(value)
  ListInputProvider->>ListInputProvider: parse (URL/IP)
  alt invalid target
    ListInputProvider->>Options: check TargetsFilePath / Targets
    alt Single-target mode
      ListInputProvider->>Logger: info("invalid target ...")
      ListInputProvider->>OS: Exit(1)
    else Batch mode
      ListInputProvider->>Logger: warn("skipping invalid target ...")
      ListInputProvider-->>User: return (skip)
    end
  else IP deletion
    ListInputProvider->>ListInputProvider: metaInput.Input = value
    ListInputProvider-->>User: proceed (delete)
  else URL deletion
    ListInputProvider-->>User: proceed (delete)
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Assessment against linked issues

Objective Addressed Explanation
Reduce extra verbose logging on unresponsive hosts; ensure only one error log (#6416) Changes focus on invalid target parsing/hostname; unresponsive host behavior not shown here.

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
Add options *types.Options to ListInputProvider and wire through constructor (pkg/input/provider/list/hmap.go) Expands provider state unrelated to controlling verbose logs for unresponsive hosts.
Introduce os.Exit(1) on invalid single-target inputs (pkg/input/provider/list/hmap.go) Alters process termination behavior, not specified in the logging bug objective.
Change Del to use metaInput.Input = value for IP deletions (pkg/input/provider/list/hmap.go) Adjusts deletion semantics; not tied to reducing verbose logs on unresponsive hosts.

Possibly related PRs

Poem

I hop through lists with careful cheer,
One target? I’ll halt—batch mode? I steer.
Logs now whisper, not a storm,
Invalid crumbs, I don’t perform.
With options tucked beneath my ear,
I prune and set—precise and clear. 🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • 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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/input/provider/list/hmap.go (1)

448-451: Use the trimmed URL when setting metaInput.Input (consistency bug).

Using value (untrimmed) can change the delItem key/parse behavior vs Set which uses URL (trimmed). This can make exclusions fail to match.

-					metaInput := contextargs.NewMetaInput()
-					metaInput.Input = value
+					metaInput := contextargs.NewMetaInput()
+					metaInput.Input = URL
 					metaInput.CustomIP = ip
 					i.delItem(metaInput)
🧹 Nitpick comments (3)
pkg/input/provider/list/hmap.go (3)

41-41: Storing global options on the provider — add a clear contract (and guard nil).

Keeping a pointer to types.Options here is fine, but please document immutability expectations and add a nil-guard in New to avoid panics if someone constructs Options with a nil .Options.

Example guard near New(...):

if opts == nil || opts.Options == nil {
	return nil, errors.New("list input provider: options must be non-nil")
}

74-74: Initialize options with an early nil-check.

New dereferences multiple fields on options later; protect against nil to fail fast with a helpful error.

if options == nil {
	return nil, errors.New("list input provider: options must be non-nil")
}

538-539: Regex errors ignored; untrusted patterns can backfire.

regexp.MatchString(metaInput.Input, tmpUrl.Host) ignores compile errors and may ReDoS. Compile once, handle error, and pre-validate exclude patterns.

-		matched, _ := regexp.MatchString(metaInput.Input, tmpUrl.Host)
+		re, reErr := regexp.Compile(metaInput.Input)
+		if reErr != nil {
+			gologger.Warning().Msgf("invalid exclude regex %q: %v", metaInput.Input, reErr)
+			return nil
+		}
+		matched := re.MatchString(tmpUrl.Host)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 48c389b and 7b2094d.

📒 Files selected for processing (1)
  • pkg/input/provider/list/hmap.go (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
pkg/input/provider/list/hmap.go (1)
pkg/types/types.go (1)
  • Options (32-464)
🔇 Additional comments (1)
pkg/input/provider/list/hmap.go (1)

62-109: Clarify timeout error suppression vs parse-time exits

  • This change only suppresses parse-time invalid-target logs (os.Exit in pkg/input/provider/list/hmap.go at lines 159–161 and 409–413).
  • It does not address the repeated network-layer timeout errors for unresponsive hosts (issue #6416); I found no gologger logs for connection timeouts in pkg—please verify where timeouts are handled/retried and adjust logging accordingly.

Comment on lines +151 to +166
if err != nil {
gologger.Error().Msgf("Failed to parse URL %v: %v", URL, err)
} else {
gologger.Error().Msgf("Invalid hostname for URL %v", URL)
}

// Check if this is single target mode (-u) or batch mode (-l)
if i.options.TargetsFilePath == "" && len(i.options.Targets) <= 1 {
// Single target mode: exit immediately
gologger.Info().Msg("Stopping scan due to invalid target")
os.Exit(1)
} else {
// Batch mode: log error and skip this target
gologger.Warning().Msgf("Skipping invalid target: %v", URL)
return
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Invalid-target handling: wrong single-target detection, duplicate logs, and os.Exit in library code.

  • Misclassification: stdin/uncover-only runs (Targets==0, TargetsFilePath=="") are treated as “single-target”, causing premature exit on any bad line.
  • Duplicate logs: you emit an Error then an Info/Warning for the same invalid input.
  • os.Exit here makes the package kill the process; better keep exit decisions at the CLI/runner layer.

Minimum fix: correct detection and emit a single message; keep exit only if you must. Suggested patch:

-		if err != nil {
-			gologger.Error().Msgf("Failed to parse URL %v: %v", URL, err)
-		} else {
-			gologger.Error().Msgf("Invalid hostname for URL %v", URL)
-		}
-		
-		// Check if this is single target mode (-u) or batch mode (-l)
-		if i.options.TargetsFilePath == "" && len(i.options.Targets) <= 1 {
-			// Single target mode: exit immediately
-			gologger.Info().Msg("Stopping scan due to invalid target")
-			os.Exit(1)
-		} else {
-			// Batch mode: log error and skip this target
-			gologger.Warning().Msgf("Skipping invalid target: %v", URL)
-			return
-		}
+		// Single clear message + correct single/batch detection
+		reason := "empty hostname"
+		if err != nil {
+			reason = err.Error()
+		}
+		if i.isSingleTargetMode() {
+			gologger.Error().Msgf("Invalid target %v: %v", URL, reason)
+			// Ideally propagate to caller instead of exiting here.
+			os.Exit(1)
+		} else {
+			gologger.Warning().Msgf("Skipping invalid target %v: %v", URL, reason)
+			return
+		}

Add this helper once in the file:

func (i *ListInputProvider) isSingleTargetMode() bool {
	if i == nil || i.options == nil {
		return false
	}
	// Consider only explicit -u usage; stdin/-l/uncover are batch-like.
	return i.options.TargetsFilePath == "" &&
		!i.options.Stdin &&
		!i.options.Uncover &&
		len(i.options.Targets) == 1
}

If feasible, prefer bubbling an error to the caller instead of os.Exit to keep package-level code side-effect free. I can draft that refactor if you want.

🤖 Prompt for AI Agents
In pkg/input/provider/list/hmap.go around lines 151 to 166: the current logic
misdetects single-target mode (treats stdin/uncover runs as single-target),
emits duplicate logs for the same invalid URL, and calls os.Exit from library
code; fix by adding a helper method isSingleTargetMode on ListInputProvider that
returns true only when TargetsFilePath=="" AND Targets length == 1 AND explicit
flags Stdin and Uncover are false (also guard i/options nil), replace the
current detection with that helper, remove the redundant Error+Info/Warning pair
so only one log entry is emitted for an invalid target, and do NOT call os.Exit
here — instead return an error or a sentinel so the CLI/runner layer can decide
to exit; if you prefer, change the function signature to return an error so
callers can handle exit behavior.

Comment on lines +401 to +416
if err != nil {
gologger.Error().Msgf("Failed to parse URL %v: %v", URL, err)
} else {
gologger.Error().Msgf("Invalid hostname for URL %v", URL)
}

// Check if this is single target mode (-u) or batch mode (-l)
if i.options.TargetsFilePath == "" && len(i.options.Targets) <= 1 {
// Single target mode: exit immediately
gologger.Info().Msg("Stopping scan due to invalid target")
os.Exit(1)
} else {
// Batch mode: log error and skip this target
gologger.Warning().Msgf("Skipping invalid target: %v", URL)
return
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Don’t os.Exit from Del; treat invalid excludes as non-fatal and skip.

Exiting from Del can kill a scan due to an invalid exclude pattern even in -l/stdin runs. Keep it a single warning and continue.

-		if err != nil {
-			gologger.Error().Msgf("Failed to parse URL %v: %v", URL, err)
-		} else {
-			gologger.Error().Msgf("Invalid hostname for URL %v", URL)
-		}
-		
-		// Check if this is single target mode (-u) or batch mode (-l)
-		if i.options.TargetsFilePath == "" && len(i.options.Targets) <= 1 {
-			// Single target mode: exit immediately
-			gologger.Info().Msg("Stopping scan due to invalid target")
-			os.Exit(1)
-		} else {
-			// Batch mode: log error and skip this target
-			gologger.Warning().Msgf("Skipping invalid target: %v", URL)
-			return
-		}
+		reason := "empty hostname"
+		if err != nil {
+			reason = err.Error()
+		}
+		gologger.Warning().Msgf("Skipping invalid exclude target %v: %v", URL, reason)
+		return
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if err != nil {
gologger.Error().Msgf("Failed to parse URL %v: %v", URL, err)
} else {
gologger.Error().Msgf("Invalid hostname for URL %v", URL)
}
// Check if this is single target mode (-u) or batch mode (-l)
if i.options.TargetsFilePath == "" && len(i.options.Targets) <= 1 {
// Single target mode: exit immediately
gologger.Info().Msg("Stopping scan due to invalid target")
os.Exit(1)
} else {
// Batch mode: log error and skip this target
gologger.Warning().Msgf("Skipping invalid target: %v", URL)
return
}
// Treat invalid exclude patterns as non-fatal—just warn and skip
reason := "empty hostname"
if err != nil {
reason = err.Error()
}
gologger.Warning().Msgf("Skipping invalid exclude target %v: %v", URL, reason)
return
🤖 Prompt for AI Agents
In pkg/input/provider/list/hmap.go around lines 401 to 416, the code currently
calls os.Exit(1) when encountering an invalid target, which terminates the
entire scan; instead, treat invalid excludes/non-fatal parse failures as
non-fatal: remove the os.Exit call, change the logic so that both single-target
and batch runs log an appropriate warning or info and return to skip processing
this target (for single-target mode, return an error to the caller or set a
non-fatal status rather than exiting), ensuring the function does not terminate
the process and batch/stdin runs continue.

Copy link
Member

@dwisiswant0 dwisiswant0 left a comment

Choose a reason for hiding this comment

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

Just a quick note: this case is kind of similar on the surface, but the behavior we’re chasing here is different from the linked issue.

Unresolved questions/TODOs:

  • How's the behavior if the target is successfully resolved (valid hostname/IP address)? -- this is the primary case for #6416.
  • Can you verify that this also works with the SDK? -- integration test may be needed.

@Mzack9999 Mzack9999 self-requested a review September 15, 2025 13:06
Copy link
Member

@Mzack9999 Mzack9999 left a comment

Choose a reason for hiding this comment

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

  • failing tests

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.

[BUG] Fix extra logging when running in verbose mode on unresponsive hosts

3 participants