diff --git a/internal/attack/incremental.go b/internal/attack/incremental.go index 527d3ea..8d4d001 100644 --- a/internal/attack/incremental.go +++ b/internal/attack/incremental.go @@ -86,10 +86,12 @@ func findChannelIncrement(route string) (incrementalRoute, bool) { // findLastNumber finds the last numeric token in the route so it can be incremented. // This supports routes where the channel number is not the final component. func findLastNumber(route string) (incrementalRoute, bool) { - for i := len(route) - 1; i >= 0; i-- { + for i := len(route) - 1; i >= 0; { if !isDigit(route[i]) { + i-- continue } + end := i + 1 start := i for start >= 0 && isDigit(route[start]) { @@ -99,7 +101,8 @@ func findLastNumber(route string) (incrementalRoute, bool) { num, width, ok := parseNumber(route, start, end) if !ok { - return incrementalRoute{}, false + i = start - 1 + continue } return incrementalRoute{ diff --git a/internal/attack/incremental_test.go b/internal/attack/incremental_test.go index c22e579..6c4a5df 100644 --- a/internal/attack/incremental_test.go +++ b/internal/attack/incremental_test.go @@ -54,6 +54,18 @@ func TestDetectIncrementalRoute_NoNumber(t *testing.T) { assert.Equal(t, incrementalRoute{}, match) } +func TestDetectIncrementalRoute_OverflowAtEndFallsBack(t *testing.T) { + // The trailing token overflows strconv.Atoi, so we fall back to earlier numbers. + route := "/foo1/bar999999999999999999999999999999" + + match, ok := detectIncrementalRoute(route) + require.True(t, ok) + assert.False(t, match.isChannel) + assert.Equal(t, 1, match.number) + assert.Equal(t, "/foo", match.prefix) + assert.Equal(t, "/bar999999999999999999999999999999", match.suffix) +} + func TestBuildIncrementedRoute_ZeroPadding(t *testing.T) { match := incrementalRoute{ prefix: "/channel",