media: never project zero image/video dimensions (crashes Telegram Desktop on reactions)
This commit is contained in:
parent
233a2399e9
commit
f26468ef6d
3 changed files with 122 additions and 4 deletions
|
|
@ -367,6 +367,11 @@ func tgPhotoSizes(sizes []domain.PhotoSize) []tg.PhotoSizeClass {
|
|||
func tgPhotoSize(s domain.PhotoSize) tg.PhotoSizeClass {
|
||||
switch s.Kind {
|
||||
case domain.PhotoSizeKindDefault:
|
||||
if s.W <= 0 || s.H <= 0 {
|
||||
// A zero-dimension photoSize is malformed and divides to a crash on
|
||||
// the client; dropping it lets clients fall back to another size.
|
||||
return nil
|
||||
}
|
||||
return &tg.PhotoSize{Type: s.Type, W: s.W, H: s.H, Size: s.Size}
|
||||
case domain.PhotoSizeKindStripped:
|
||||
return &tg.PhotoStrippedSize{Type: s.Type, Bytes: s.Bytes}
|
||||
|
|
@ -464,12 +469,47 @@ func compactPhotoSizeClasses(in []tg.PhotoSizeClass) []tg.PhotoSizeClass {
|
|||
return out
|
||||
}
|
||||
|
||||
// stickerCanvasSize is the square canvas a sticker / custom emoji is laid out on.
|
||||
// It is the fallback dimension when stored metadata carries a zero, which clients
|
||||
// divide by while sizing the render (a 0 there crashes Telegram Desktop).
|
||||
const stickerCanvasSize = 512
|
||||
|
||||
func stickerLikeMime(mimeType string) bool {
|
||||
switch mimeType {
|
||||
case mimeApplicationXTGSticker, "image/webp", "video/webm":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// safeMediaDimension replaces a non-positive width/height with a usable value:
|
||||
// the sticker canvas for sticker-like documents, otherwise 1, so no projected
|
||||
// attribute ever carries a zero a client would divide by.
|
||||
func safeMediaDimension(v int, mimeType string) int {
|
||||
if v > 0 {
|
||||
return v
|
||||
}
|
||||
if stickerLikeMime(mimeType) {
|
||||
return stickerCanvasSize
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
func tgDocumentAttributes(mimeType string, attrs []domain.DocumentAttribute) []tg.DocumentAttributeClass {
|
||||
out := make([]tg.DocumentAttributeClass, 0, len(attrs))
|
||||
for _, a := range attrs {
|
||||
switch a.Kind {
|
||||
case domain.DocAttrImageSize:
|
||||
out = append(out, &tg.DocumentAttributeImageSize{W: a.W, H: a.H})
|
||||
if (a.W <= 0 || a.H <= 0) && !stickerLikeMime(mimeType) {
|
||||
// Malformed size on a plain image: drop it rather than emit a zero.
|
||||
// Clients cope with a missing imageSize; a zero one crashes them.
|
||||
continue
|
||||
}
|
||||
out = append(out, &tg.DocumentAttributeImageSize{
|
||||
W: safeMediaDimension(a.W, mimeType),
|
||||
H: safeMediaDimension(a.H, mimeType),
|
||||
})
|
||||
case domain.DocAttrAnimated:
|
||||
if mimeType == mimeApplicationXTGSticker {
|
||||
continue
|
||||
|
|
@ -487,8 +527,8 @@ func tgDocumentAttributes(mimeType string, attrs []domain.DocumentAttribute) []t
|
|||
SupportsStreaming: a.SupportsStreaming,
|
||||
Nosound: a.NoSound,
|
||||
Duration: a.Duration,
|
||||
W: a.W,
|
||||
H: a.H,
|
||||
W: safeMediaDimension(a.W, mimeType),
|
||||
H: safeMediaDimension(a.H, mimeType),
|
||||
}
|
||||
if a.VideoCodec != "" {
|
||||
video.SetVideoCodec(a.VideoCodec)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue