152 lines
4.9 KiB
Go
152 lines
4.9 KiB
Go
package attack
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestDetectIncrementalRoute_ChannelID(t *testing.T) {
|
|
route := "/StreamingSetting?version=1.0&action=getRTSPStream&ChannelID=01&ChannelName=Channel1"
|
|
|
|
match, ok := detectIncrementalRoute(route)
|
|
require.True(t, ok)
|
|
assert.True(t, match.isChannel)
|
|
assert.Equal(t, 1, match.number)
|
|
assert.Equal(t, 2, match.width)
|
|
assert.Equal(t, "/StreamingSetting?version=1.0&action=getRTSPStream&ChannelID=", match.prefix)
|
|
assert.Equal(t, "&ChannelName=Channel1", match.suffix)
|
|
|
|
next := buildIncrementedRoute(match, match.number+1)
|
|
assert.Equal(t, "/StreamingSetting?version=1.0&action=getRTSPStream&ChannelID=02&ChannelName=Channel1", next)
|
|
}
|
|
|
|
func TestDetectIncrementalRoute_ChannelSuffix(t *testing.T) {
|
|
route := "/path/to/channel2/stream"
|
|
|
|
match, ok := detectIncrementalRoute(route)
|
|
require.True(t, ok)
|
|
assert.True(t, match.isChannel)
|
|
assert.Equal(t, 2, match.number)
|
|
assert.Equal(t, "/path/to/channel", match.prefix)
|
|
assert.Equal(t, "/stream", match.suffix)
|
|
}
|
|
|
|
func TestDetectIncrementalRoute_LastNumber(t *testing.T) {
|
|
route := "/foo/bar12/baz"
|
|
|
|
match, ok := detectIncrementalRoute(route)
|
|
require.True(t, ok)
|
|
assert.False(t, match.isChannel)
|
|
assert.Equal(t, 12, match.number)
|
|
assert.Equal(t, 2, match.width)
|
|
assert.Equal(t, "/foo/bar", match.prefix)
|
|
assert.Equal(t, "/baz", match.suffix)
|
|
|
|
next := buildIncrementedRoute(match, 13)
|
|
assert.Equal(t, "/foo/bar13/baz", next)
|
|
}
|
|
|
|
func TestDetectIncrementalRoute_NoNumber(t *testing.T) {
|
|
match, ok := detectIncrementalRoute("/no/number/here")
|
|
assert.False(t, ok)
|
|
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 TestDetectIncrementalRoute_ChannelKeywordShouldNotBindAcrossParams(t *testing.T) {
|
|
// The channel keyword should not bind to digits in other query parameters.
|
|
route := "/path?channelname=foo&version=12"
|
|
|
|
match, ok := detectIncrementalRoute(route)
|
|
require.True(t, ok)
|
|
assert.False(t, match.isChannel)
|
|
assert.Equal(t, 12, match.number)
|
|
assert.Equal(t, "/path?channelname=foo&version=", match.prefix)
|
|
assert.Equal(t, "", match.suffix)
|
|
}
|
|
|
|
func TestDetectIncrementalRoute_ChannelKeywordStopsAtDelimiter(t *testing.T) {
|
|
// Digits after a delimiter should not be associated with a channel keyword.
|
|
route := "/path/channel?channel=foo/7"
|
|
|
|
match, ok := detectIncrementalRoute(route)
|
|
require.True(t, ok)
|
|
assert.False(t, match.isChannel)
|
|
assert.Equal(t, 7, match.number)
|
|
assert.Equal(t, "/path/channel?channel=foo/", match.prefix)
|
|
assert.Equal(t, "", match.suffix)
|
|
}
|
|
|
|
func TestDetectIncrementalRoute_ChannelKeywordWithoutDigitsFallsBack(t *testing.T) {
|
|
// channel keyword without digits should fall back to last numeric token.
|
|
route := "/path/channel?channel=foo&stream=9"
|
|
|
|
match, ok := detectIncrementalRoute(route)
|
|
require.True(t, ok)
|
|
assert.False(t, match.isChannel)
|
|
assert.Equal(t, 9, match.number)
|
|
assert.Equal(t, "/path/channel?channel=foo&stream=", match.prefix)
|
|
assert.Equal(t, "", match.suffix)
|
|
}
|
|
|
|
func TestDetectIncrementalRoute_ChannelKeywordKeepsQueryDigits(t *testing.T) {
|
|
// channel keyword with query param digits should be detected as channel.
|
|
route := "/path?channel=03&other=1"
|
|
|
|
match, ok := detectIncrementalRoute(route)
|
|
require.True(t, ok)
|
|
assert.True(t, match.isChannel)
|
|
assert.Equal(t, 3, match.number)
|
|
assert.Equal(t, 2, match.width)
|
|
assert.Equal(t, "/path?channel=", match.prefix)
|
|
assert.Equal(t, "&other=1", match.suffix)
|
|
}
|
|
|
|
func TestDetectIncrementalRoute_ChannelKeywordMultipleMatchesUsesKeywordPriority(t *testing.T) {
|
|
// Keyword priority should win even if another keyword appears earlier in the route.
|
|
route := "/path?channel=1&channelid=9"
|
|
|
|
match, ok := detectIncrementalRoute(route)
|
|
require.True(t, ok)
|
|
assert.True(t, match.isChannel)
|
|
assert.Equal(t, 9, match.number)
|
|
assert.Equal(t, "/path?channel=1&channelid=", match.prefix)
|
|
assert.Equal(t, "", match.suffix)
|
|
}
|
|
|
|
func TestDetectIncrementalRoute_ChannelKeywordSelectsLastMatchWithinKeyword(t *testing.T) {
|
|
// The last match for a given keyword should be selected.
|
|
route := "/path?channel=1&foo=bar&channel=4"
|
|
|
|
match, ok := detectIncrementalRoute(route)
|
|
require.True(t, ok)
|
|
assert.True(t, match.isChannel)
|
|
assert.Equal(t, 4, match.number)
|
|
assert.Equal(t, "/path?channel=1&foo=bar&channel=", match.prefix)
|
|
assert.Equal(t, "", match.suffix)
|
|
}
|
|
|
|
func TestBuildIncrementedRoute_ZeroPadding(t *testing.T) {
|
|
match := incrementalRoute{
|
|
prefix: "/channel",
|
|
suffix: "/stream",
|
|
number: 1,
|
|
width: 3,
|
|
}
|
|
|
|
assert.Equal(t, "/channel002/stream", buildIncrementedRoute(match, 2))
|
|
}
|