Skip to content

Conversation

@dogancanbakir
Copy link
Member

@dogancanbakir dogancanbakir commented Jan 12, 2026

Summary

Test Cases

1. Create a test Burp XML file test.xml:

<?xml version="1.0"?>
<items burpVersion="2023.10.1.2" exportTime="Sat Sep 30 20:11:44 IST 2023">
  <item>
    <url><![CDATA[http://scanme.sh/]]></url>
    <host>scanme.sh</host>
    <port>80</port>
    <protocol>http</protocol>
    <method><![CDATA[GET]]></method>
    <path><![CDATA[/]]></path>
    <extension>null</extension>
    <request base64="true"><![CDATA[R0VUIC8gSFRUUC8xLjE=]]></request>
    <status>200</status>
    <responselength>100</responselength>
    <mimetype>HTML</mimetype>
    <response base64="true"><![CDATA[T0s=]]></response>
    <comment></comment>
  </item>
  <item>
    <url><![CDATA[https://example.com/test]]></url>
    <host>example.com</host>
    <port>443</port>
    <protocol>https</protocol>
    <method><![CDATA[GET]]></method>
    <path><![CDATA[/test]]></path>
    <extension>null</extension>
    <request base64="true"><![CDATA[R0VUIC8gSFRUUC8xLjE=]]></request>
    <status>200</status>
    <responselength>100</responselength>
    <mimetype>HTML</mimetype>
    <response base64="true"><![CDATA[T0s=]]></response>
    <comment></comment>
  </item>
</items>

2. Test commands:

# Parse Burp XML and probe URLs
httpx -l test.xml -im burp

# Expected output: probes http://scanme.sh/ and https://example.com/test

# Verify help shows the flag
httpx -h | grep input-mode
# Expected: -im, -input-mode string  mode of input file (burp)

3. Run unit tests:

go test ./common/inputformats/... -v

Summary by CodeRabbit

  • New Features

    • Import Burp Suite XML export files as input sources.
    • New --input-mode/-im flag to specify and validate input file format.
    • Input handling enhanced to parse formatted inputs, stream targets with deduplication, and support early-stop during parsing.
  • Tests

    • Added tests covering Burp XML parsing, format registry behavior, empty inputs, and early-stop scenarios.
  • Documentation

    • Usage note showing how to use Burp exports with the new input-mode flag.

✏️ Tip: You can customize this high-level summary in your review settings.

@auto-assign auto-assign bot requested a review from Mzack9999 January 12, 2026 11:14
@coderabbitai
Copy link

coderabbitai bot commented Jan 12, 2026

Walkthrough

Adds a Format interface and registry, implements a BurpFormat parser for Burp Suite XML, registers it, and integrates format-based input loading into the runner with a new --input-mode / -im option that selects parsing instead of line-based input.

Changes

Cohort / File(s) Summary
Burp Format Parser
common/inputformats/burp.go, common/inputformats/burp_test.go
New BurpFormat with Name() and Parse(input, callback) using burpxml.Parse; skips empty URLs, supports early-stop via callback. Tests cover normal parsing, empty input, and early termination.
Format Registry System
common/inputformats/formats.go, common/inputformats/formats_test.go
Adds Format interface, registry initialized with NewBurpFormat(), GetFormat(name) (case-insensitive) and SupportedFormats(); tests validate lookups and supported list.
Runner Options
runner/options.go
Adds InputMode string to Options, exposes --input-mode / -im flag and validates it against registered formats; enforces -im requires -l.
Format-Based Input Loading
runner/runner.go
Adds getInputFormat() and loadFromFormat(...); integrates format parsing into prepareInput and streamInput, feeding parsed URLs into existing dedup/trim logic and handling parse errors.
Dependencies
go.mod
Adds dependency on github.com/seh-msft/burpxml v1.0.1 to parse Burp XML.

Sequence Diagram(s)

sequenceDiagram
    participant Runner
    participant Formats as FormatRegistry
    participant File as InputFile
    participant Burp as BurpParser
    participant Callback as URLProcessor

    Runner->>Formats: GetFormat(InputMode)
    Formats-->>Runner: BurpFormat
    Runner->>File: open(filePath)
    File-->>Runner: file handle
    Runner->>Burp: Parse(file, callback)
    Burp->>File: read XML
    Burp->>Burp: unmarshal items
    loop for each item with URL
        Burp->>Callback: callback(url)
        Callback->>Callback: trim/expand/dedupe
        Callback-->>Burp: continue or stop
    end
    Burp-->>Runner: return nil or error
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I found a Burp file beneath the log,

I hopped through tags and chased each HTTP frog,
-im burp on my flag, I parse with delight,
yielding URLs by soft moonlight,
a tiny rabbit's parsing jog 🥕🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 36.36% 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 PR title accurately reflects the primary change: adding Burp XML input mode support via a new -im flag, which is the core focus of all code changes.
Linked Issues check ✅ Passed The PR fully implements the objectives from issue #2359: introduces -im/--input-mode flag, implements Burp Suite XML parsing, and extracts URLs from entries for httpx probing.
Out of Scope Changes check ✅ Passed All code changes are directly scoped to the Burp Suite XML import feature: new input format interface, Burp parser implementation, flag integration, and documentation updates with no unrelated modifications.

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

✨ Finishing touches
  • 📝 Generate docstrings

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

🤖 Fix all issues with AI agents
In @go.mod:
- Line 142: The go.mod entry for github.com/seh-msft/burpxml is incorrectly
marked as indirect even though it is directly imported from
common/inputformats/burp.go; fix this by running `go mod tidy` in the repository
root to regenerate go.mod/go.sum (or remove the `// indirect` annotation for the
github.com/seh-msft/burpxml line and then run `go mod tidy`), then verify the
import in common/inputformats/burp.go still builds and commit the updated
go.mod/go.sum.

In @runner/runner.go:
- Around line 659-665: streamInput currently discards the error from
format.Parse which hides parse failures; change the call in streamInput to
capture the returned error (err := format.Parse(...)), and then handle it the
same way prepareInput does — i.e., log or return the error instead of assigning
to `_`; keep the same parsing callback that uses r.options.SkipDedupe and
r.testAndSet to send items to out so only the Parse error handling changes.
🧹 Nitpick comments (5)
runner/options.go (1)

380-380: Add InputMode validation to ValidateOptions() for early error detection.

Currently, invalid InputMode values cause a gologger.Fatal() error during execution (runner.go lines 532, 651) rather than failing early during validation. Moving this check to ValidateOptions() will provide cleaner error handling and fail faster with a proper validation error.

Suggested addition in ValidateOptions()
if options.InputMode != "" && inputformats.GetFormat(options.InputMode) == nil {
	return fmt.Errorf("invalid input mode '%s', supported formats: %s", options.InputMode, inputformats.SupportedFormats())
}
common/inputformats/burp_test.go (2)

68-73: Consider adding bounds check before index access.

If Parse returns fewer URLs than expected (e.g., due to a bug), accessing urls[i] will panic with an index out of range error rather than providing a clear test failure message.

💡 Suggested improvement
 	expectedURLs := []string{"http://example.com/path1", "https://example.com/path2"}
+	if len(urls) != len(expectedURLs) {
+		t.Fatalf("Expected %d URLs, got %d: %v", len(expectedURLs), len(urls), urls)
+	}
 	for i, expected := range expectedURLs {
-		if urls[i] != expected {
+		if i < len(urls) && urls[i] != expected {
 			t.Errorf("Expected URL %d to be '%s', got '%s'", i, expected, urls[i])
 		}
 	}

1-148: Consider adding a test for malformed XML.

The test suite covers valid XML scenarios well, but doesn't test error handling for malformed or invalid XML input. This would help ensure the parser returns appropriate errors rather than panicking.

💡 Suggested test case
func TestBurpFormat_ParseMalformed(t *testing.T) {
	malformedXML := `<?xml version="1.0"?>
<items burpVersion="2023.10.1.2">
  <item>
    <url><![CDATA[http://example.com/path1]]></url>
    <!-- missing closing tag -->
</items>`

	b := NewBurpFormat()
	err := b.Parse(strings.NewReader(malformedXML), func(url string) bool {
		return true
	})

	if err == nil {
		t.Error("Expected error for malformed XML, got nil")
	}
}
runner/runner.go (2)

647-676: Duplicate format validation logic should be extracted.

The format lookup and validation logic (lines 649-652) is duplicated from prepareInput (lines 530-533). Consider extracting this into a helper function to maintain DRY principles.

♻️ Suggested helper function
// getInputFormat validates and returns the format for the given input mode.
// Returns nil and logs fatal if the format is invalid.
func (r *Runner) getInputFormat() inputformats.Format {
	if r.options.InputMode == "" {
		return nil
	}
	format := inputformats.GetFormat(r.options.InputMode)
	if format == nil {
		gologger.Fatal().Msgf("Invalid input mode '%s'. Supported: %s\n", r.options.InputMode, inputformats.SupportedFormats())
	}
	return format
}

Then use it in both prepareInput and streamInput.


737-751: Shadow variable err inside callback may cause confusion.

The callback declares err on line 739 which shadows the outer err from line 737. While this doesn't cause a bug (the outer err is reassigned by format.Parse), it could lead to maintenance issues. Consider renaming the inner variable.

💡 Suggested improvement
 	err = format.Parse(finput, func(target string) bool {
 		target = strings.TrimSpace(target)
-		expandedTarget, err := r.countTargetFromRawTarget(target)
-		if err == nil && expandedTarget > 0 {
+		expandedTarget, countErr := r.countTargetFromRawTarget(target)
+		if countErr == nil && expandedTarget > 0 {
 			numTargets += expandedTarget
 			r.hm.Set(target, []byte("1")) //nolint
-		} else if r.options.SkipDedupe && errors.Is(err, duplicateTargetErr) {
+		} else if r.options.SkipDedupe && errors.Is(countErr, duplicateTargetErr) {
 			if v, ok := r.hm.Get(target); ok {
 				cnt, _ := strconv.Atoi(string(v))
 				_ = r.hm.Set(target, []byte(strconv.Itoa(cnt+1)))
 				numTargets += 1
 			}
 		}
 		return true
 	})
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 59adfd6 and 0f5141b.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (7)
  • common/inputformats/burp.go
  • common/inputformats/burp_test.go
  • common/inputformats/formats.go
  • common/inputformats/formats_test.go
  • go.mod
  • runner/options.go
  • runner/runner.go
🧰 Additional context used
🧬 Code graph analysis (4)
common/inputformats/burp.go (1)
common/inputformats/formats.go (1)
  • Format (11-17)
common/inputformats/formats.go (1)
common/inputformats/burp.go (1)
  • NewBurpFormat (14-16)
runner/options.go (1)
common/inputformats/formats.go (1)
  • SupportedFormats (35-41)
common/inputformats/burp_test.go (1)
common/inputformats/burp.go (1)
  • NewBurpFormat (14-16)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: Test Builds (ubuntu-latest)
  • GitHub Check: Test Builds (macOS-latest)
  • GitHub Check: Test Builds (windows-latest)
  • GitHub Check: Functional Test (ubuntu-latest)
  • GitHub Check: Functional Test (windows-latest)
  • GitHub Check: Functional Test (macOS-latest)
  • GitHub Check: Analyze (go)
  • GitHub Check: release-test
🔇 Additional comments (16)
common/inputformats/formats_test.go (2)

8-36: LGTM!

Well-structured table-driven tests covering case-insensitivity, invalid inputs, and edge cases for the format registry lookup.


38-43: LGTM!

Basic validation that "burp" format is registered. Consider adding a test that verifies the exact count of supported formats if the registry is expected to grow.

common/inputformats/formats.go (3)

10-17: LGTM!

Clean interface design. The callback returning bool for early termination is a good pattern for streaming large input files.


19-22: LGTM!

Format registry is properly initialized at package load time. The slice-based approach is appropriate for the expected small number of formats.


24-41: LGTM!

Case-insensitive lookup is user-friendly. The implementation is straightforward and correct.

common/inputformats/burp.go (2)

18-18: LGTM!

Good practice using compile-time interface assertion to ensure BurpFormat implements Format.


27-42: LGTM!

The implementation correctly handles:

  • Parse errors with contextual wrapping
  • Empty URLs (skipped)
  • Early termination via callback return value

Consider whether URL validation (e.g., url.Parse) would be beneficial before invoking the callback, though downstream consumers may already handle malformed URLs gracefully.

runner/options.go (2)

26-26: LGTM!

Import added correctly for the new inputformats package.


195-195: LGTM!

Field follows existing naming conventions (InputFile, InputMode).

common/inputformats/burp_test.go (4)

8-13: LGTM!

Simple and effective test for verifying the format name.


15-74: LGTM!

Comprehensive test covering the happy path with realistic Burp XML data including CDATA sections, base64-encoded requests/responses, and multiple items.


76-96: LGTM!

Good edge case coverage for empty XML input.


98-148: LGTM!

Good test for early termination behavior via callback returning false. This validates that the parser respects the callback's signal to stop processing.

runner/runner.go (3)

38-38: LGTM!

Import correctly added for the new inputformats package.


528-548: LGTM!

Good implementation with proper validation of the input mode against supported formats, clear error messages, and appropriate fallback to line-based file reading when no format is specified.


730-753: LGTM!

The loadFromFormat method follows the same pattern as loadAndCloseFile, correctly handling target counting, deduplication, and the SkipDedupe option. Good use of defer for file cleanup.

Mzack9999 and others added 2 commits January 12, 2026 15:23
- Handle error from format.Parse in streamInput
- Add InputMode validation to ValidateOptions for early error detection
- Extract duplicate format validation to getInputFormat helper
- Fix shadow variable err in loadFromFormat callback
- Add bounds check in test before index access
- Add test for malformed XML input
- Run go mod tidy to fix dependency marking
@dogancanbakir
Copy link
Member Author

also, projectdiscovery/utils#722

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: 0

🧹 Nitpick comments (1)
common/inputformats/burp_test.go (1)

64-76: Redundant length checks can be consolidated.

The check at lines 64-66 (len(urls) != 2) is redundant with the check at lines 69-71 (len(urls) != len(expectedURLs)), since expectedURLs is always length 2. The first check uses t.Errorf (continues), so if it fails, both messages will be logged before t.Fatalf stops execution.

Consider removing lines 64-66 to keep only the more informative check.

♻️ Suggested simplification
 	if err != nil {
 		t.Fatalf("Parse returned error: %v", err)
 	}

-	if len(urls) != 2 {
-		t.Errorf("Expected 2 URLs, got %d", len(urls))
-	}
-
 	expectedURLs := []string{"http://example.com/path1", "https://example.com/path2"}
 	if len(urls) != len(expectedURLs) {
 		t.Fatalf("Expected %d URLs, got %d: %v", len(expectedURLs), len(urls), urls)
 	}
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0f5141b and 430e33f.

📒 Files selected for processing (4)
  • common/inputformats/burp_test.go
  • go.mod
  • runner/options.go
  • runner/runner.go
✅ Files skipped from review due to trivial changes (1)
  • runner/options.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • go.mod
🧰 Additional context used
🧬 Code graph analysis (2)
runner/runner.go (1)
common/inputformats/formats.go (3)
  • Format (11-17)
  • GetFormat (25-32)
  • SupportedFormats (35-41)
common/inputformats/burp_test.go (1)
common/inputformats/burp.go (1)
  • NewBurpFormat (14-16)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Test Builds (macOS-latest)
  • GitHub Check: Test Builds (windows-latest)
  • GitHub Check: Functional Test (windows-latest)
🔇 Additional comments (9)
common/inputformats/burp_test.go (4)

8-13: LGTM!

Simple and effective test for the Name() method.


79-99: LGTM!

Good coverage for the empty input edge case.


101-151: LGTM!

Good test coverage for the early-stop callback behavior.


153-169: LGTM!

Good negative test case for malformed XML handling.

runner/runner.go (5)

38-38: LGTM!

Import added for the new inputformats package integration.


528-544: LGTM!

Clean integration of format-based input handling with appropriate fallback to line-based reading.


637-648: LGTM!

Well-designed helper that centralizes format validation and provides clear error messages for invalid input modes.


656-684: LGTM!

Good implementation of format-based streaming with proper resource cleanup and error handling. The callback correctly applies TrimSpace and deduplication logic consistent with the line-based path.


738-761: LGTM!

Clean implementation that correctly mirrors the line-based loadAndCloseFile logic while using format-based parsing. The use of countErr instead of shadowing err is a good fix.

@Mzack9999 Mzack9999 added the Type: Enhancement Most issues will probably ask for additions or changes. label Jan 12, 2026
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: 0

🧹 Nitpick comments (1)
README.md (1)

98-98: Consider clarifying the flag description.

The description "mode of input file (burp)" could be more explicit about what "mode" means. Consider rephrasing to improve clarity, such as:

  • "input file format (supported: burp)"
  • "format of input file (e.g., burp for Burp Suite XML)"

This would help users immediately understand that the flag specifies the file format/type.

📝 Suggested description improvement
-   -im, -input-mode string       mode of input file (burp)
+   -im, -input-mode string       input file format (supported: burp)
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 430e33f and f445b0a.

📒 Files selected for processing (3)
  • README.md
  • common/inputformats/burp.go
  • runner/options.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • runner/options.go
  • common/inputformats/burp.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Test Builds (windows-latest)
  • GitHub Check: Test Builds (ubuntu-latest)
  • GitHub Check: Test Builds (macOS-latest)
  • GitHub Check: Functional Test (windows-latest)
  • GitHub Check: Functional Test (ubuntu-latest)
  • GitHub Check: Functional Test (macOS-latest)
  • GitHub Check: Analyze (go)
🔇 Additional comments (1)
README.md (1)

283-283: LGTM!

The note provides clear, actionable guidance with a concrete example showing how to use Burp Suite XML exports with the new -im flag.

@dogancanbakir dogancanbakir merged commit f6aa159 into dev Jan 12, 2026
15 checks passed
@dogancanbakir dogancanbakir deleted the feature/input-mode-burp branch January 12, 2026 11:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Type: Enhancement Most issues will probably ask for additions or changes.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Burp Suite import functionality (-im burp, --input-mode burp)

3 participants