package video import ( "context" "fmt" "os/exec" "strings" ) // Decompression-bomb guard. A 100 KB webm can carry a 16383x16383 VP8 frame // (the format's maximum): tiny on disk, ~1 GB once ffmpeg expands it to raw // pixels. Probing the container header is cheap -- ffprobe reads metadata and // never decodes a frame -- so we reject absurd geometry before any decoding. const ( MaxDimension = 4096 MaxPixels = 8 << 20 // 8 Mpx, ~4x a 1080p frame ) func checkGeometry(ctx context.Context, inp string) error { args := []string{"-v", "error", "-select_streams", "v:0", "-show_entries", "stream=width,height", "-of", "csv=s=x:p=0", inp} // FAIL-OPEN on purpose. A probe that errors out or prints something we do // not understand must NOT reject the upload: the checker's video would // start failing with "cannot create video" and that costs more than the // bomb does. Only a geometry we successfully read and that is absurd is // rejected. Bombs need a real, huge, parseable resolution to be bombs. out, err := exec.CommandContext(ctx, "ffprobe", args...).Output() if err != nil { return nil } var w, h int if _, err := fmt.Sscanf(strings.TrimSpace(string(out)), "%dx%d", &w, &h); err != nil { return nil } if w <= 0 || h <= 0 { return nil } if w > MaxDimension || h > MaxDimension || w*h > MaxPixels { return fmt.Errorf("video resolution %dx%d is not supported", w, h) } return nil }