We should use `(*regexp.Regexp).MatchString` instead of
`(*regexp.Regexp).Match([]byte(...))` when matching string to avoid
unnecessary `[]byte` conversions and reduce allocations.
Example benchmark:
var allowedOrigin = regexp.MustCompile(".*.example.com")
func BenchmarkMatch(b *testing.B) {
for i := 0; i < b.N; i++ {
if match := allowedOrigin.Match([]byte("www.example.com")); !match {
b.Fail()
}
}
}
func BenchmarkMatchString(b *testing.B) {
for i := 0; i < b.N; i++ {
if match := allowedOrigin.MatchString("wwww.example.com"); !match {
b.Fail()
}
}
}
goos: linux
goarch: amd64
pkg: github.com/gotify/server/v2/api/stream
cpu: AMD Ryzen 7 PRO 4750U with Radeon Graphics
BenchmarkMatch-16 2076819 647.7 ns/op 16 B/op 1 allocs/op
BenchmarkMatchString-16 2536326 442.0 ns/op 0 B/op 0 allocs/op
PASS
ok github.com/gotify/server/v2/api/stream 3.552s
Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
The application image file upload allowed authenticated users to upload
malious .html files. Opening such a file like
https://push.gotify.net/image/ViaxrjzNowdgL-xnEfVV-Ggv5.html
would allow the attacker to execute client side scripts.
The application image upload will now only allow the upload of files
with the following extensions: .gif, .png, .jpg and .jpeg.
Can be enabled via the registration config flag. (disabled per default)
Fixesgotify/server#395
Co-authored-by: pigpig <pigpig@pig.pig>
Co-authored-by: Karmanyaah Malhotra <32671690+karmanyaahm@users.noreply.github.com>
Co-authored-by: Jannis Mattheis <contact@jmattheis.de>
For ids uint is used, this is platform specific and either uint32
or uint64. The parsing for parameters in the api expected the ids to
have 32bit size.
I thought about changing all our ids to int64 but we sadly have one uint
usage in the plugin api:
b0e2eca8e3/plugin.go (L13-L14)
GR = goroutine
[GR#1] http server gets closed
[GR#2] client.NotifyClose() will be executed
[GR#2] client.once.Do will be executed (lock's client.once.m)
[GR#1] stream.Close will be executed (lock's stream.lock)
[GR#1] client.Close will be executed (waits for client.once.m)
[GR#2] stream.remove will be executed (waits for stream.lock)
GR#1 holds lock stream.lock and waits for client.once.m
GR#2 holds lock client.once.m and waits for stream.lock
We prevent the deadlock with releasing the client.once.m lock earlier.