All checks were successful
check / check (push) Successful in 1m50s
Signatures are per-URL, so the whitelist should only support exact host matches. Remove the suffix/wildcard matching that allowed patterns like '.example.com' to bypass signature requirements for entire domain trees. Leading dots in existing config entries are now stripped, so '.example.com' becomes 'example.com' as an exact match (backwards-compatible normalisation).
196 lines
4.2 KiB
Go
196 lines
4.2 KiB
Go
package imgcache
|
|
|
|
import (
|
|
"net/url"
|
|
"testing"
|
|
)
|
|
|
|
func TestHostWhitelist_IsWhitelisted(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
patterns []string
|
|
testURL string
|
|
want bool
|
|
}{
|
|
{
|
|
name: "exact match",
|
|
patterns: []string{"cdn.example.com"},
|
|
testURL: "https://cdn.example.com/image.jpg",
|
|
want: true,
|
|
},
|
|
{
|
|
name: "exact match case insensitive",
|
|
patterns: []string{"CDN.Example.COM"},
|
|
testURL: "https://cdn.example.com/image.jpg",
|
|
want: true,
|
|
},
|
|
{
|
|
name: "exact match not found",
|
|
patterns: []string{"cdn.example.com"},
|
|
testURL: "https://other.example.com/image.jpg",
|
|
want: false,
|
|
},
|
|
{
|
|
name: "no suffix matching for subdomains",
|
|
patterns: []string{"example.com"},
|
|
testURL: "https://cdn.example.com/image.jpg",
|
|
want: false,
|
|
},
|
|
{
|
|
name: "leading dot stripped to exact match",
|
|
patterns: []string{".example.com"},
|
|
testURL: "https://example.com/image.jpg",
|
|
want: true,
|
|
},
|
|
{
|
|
name: "leading dot does not enable suffix matching",
|
|
patterns: []string{".example.com"},
|
|
testURL: "https://cdn.example.com/image.jpg",
|
|
want: false,
|
|
},
|
|
{
|
|
name: "leading dot does not match deep subdomain",
|
|
patterns: []string{".example.com"},
|
|
testURL: "https://cdn.images.example.com/image.jpg",
|
|
want: false,
|
|
},
|
|
{
|
|
name: "multiple patterns exact only",
|
|
patterns: []string{"cdn.example.com", "photos.images.org", "static.test.net"},
|
|
testURL: "https://photos.images.org/image.jpg",
|
|
want: true,
|
|
},
|
|
{
|
|
name: "multiple patterns no suffix leak",
|
|
patterns: []string{"cdn.example.com", "images.org"},
|
|
testURL: "https://photos.images.org/image.jpg",
|
|
want: false,
|
|
},
|
|
{
|
|
name: "empty whitelist",
|
|
patterns: []string{},
|
|
testURL: "https://cdn.example.com/image.jpg",
|
|
want: false,
|
|
},
|
|
{
|
|
name: "nil url",
|
|
patterns: []string{"cdn.example.com"},
|
|
testURL: "",
|
|
want: false,
|
|
},
|
|
{
|
|
name: "url with port",
|
|
patterns: []string{"cdn.example.com"},
|
|
testURL: "https://cdn.example.com:443/image.jpg",
|
|
want: true,
|
|
},
|
|
{
|
|
name: "whitespace in patterns",
|
|
patterns: []string{" cdn.example.com ", " other.com "},
|
|
testURL: "https://cdn.example.com/image.jpg",
|
|
want: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
w := NewHostWhitelist(tt.patterns)
|
|
|
|
var u *url.URL
|
|
if tt.testURL != "" {
|
|
var err error
|
|
u, err = url.Parse(tt.testURL)
|
|
if err != nil {
|
|
t.Fatalf("failed to parse test URL: %v", err)
|
|
}
|
|
}
|
|
|
|
got := w.IsWhitelisted(u)
|
|
if got != tt.want {
|
|
t.Errorf("IsWhitelisted() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHostWhitelist_IsEmpty(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
patterns []string
|
|
want bool
|
|
}{
|
|
{
|
|
name: "empty",
|
|
patterns: []string{},
|
|
want: true,
|
|
},
|
|
{
|
|
name: "nil",
|
|
patterns: nil,
|
|
want: true,
|
|
},
|
|
{
|
|
name: "whitespace only",
|
|
patterns: []string{" ", ""},
|
|
want: true,
|
|
},
|
|
{
|
|
name: "has entries",
|
|
patterns: []string{"example.com"},
|
|
want: false,
|
|
},
|
|
{
|
|
name: "leading dot normalised to entry",
|
|
patterns: []string{".example.com"},
|
|
want: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
w := NewHostWhitelist(tt.patterns)
|
|
if got := w.IsEmpty(); got != tt.want {
|
|
t.Errorf("IsEmpty() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHostWhitelist_Count(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
patterns []string
|
|
want int
|
|
}{
|
|
{
|
|
name: "empty",
|
|
patterns: []string{},
|
|
want: 0,
|
|
},
|
|
{
|
|
name: "exact hosts only",
|
|
patterns: []string{"a.com", "b.com", "c.com"},
|
|
want: 3,
|
|
},
|
|
{
|
|
name: "leading dots normalised to exact",
|
|
patterns: []string{".a.com", ".b.com"},
|
|
want: 2,
|
|
},
|
|
{
|
|
name: "mixed deduplication",
|
|
patterns: []string{"example.com", ".example.com"},
|
|
want: 1,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
w := NewHostWhitelist(tt.patterns)
|
|
if got := w.Count(); got != tt.want {
|
|
t.Errorf("Count() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|