Use a hardcoded upper bound and add additional checks
diff --git a/lottie/src/main/java/com/airbnb/lottie/LottieDrawable.java b/lottie/src/main/java/com/airbnb/lottie/LottieDrawable.java index 69eb1a3..4d2d1d0 100644 --- a/lottie/src/main/java/com/airbnb/lottie/LottieDrawable.java +++ b/lottie/src/main/java/com/airbnb/lottie/LottieDrawable.java
@@ -111,6 +111,11 @@ "reducedmotion" ); + /** + * Significantly larger than the largest expected size, equivalent to about 1.5x an 8K display. + */ + private static final long MAX_SOFTWARE_BITMAP_PIXELS = 50_000_000L; + private LottieComposition composition; private final LottieValueAnimator animator = new LottieValueAnimator(); @@ -1795,11 +1800,22 @@ softwareRenderingTransformedBounds.intersect(canvasClipBounds.left, canvasClipBounds.top, canvasClipBounds.right, canvasClipBounds.bottom); } + if (!isFiniteRect(softwareRenderingTransformedBounds)) { + Logger.warning("Skipping software rendering: transformed bounds contain non-finite values."); + return; + } + int renderWidth = (int) Math.ceil(softwareRenderingTransformedBounds.width()); int renderHeight = (int) Math.ceil(softwareRenderingTransformedBounds.height()); - // Safeguard against errors during Bitmap creation by returning early if dimensions are invalid. - if (renderWidth <= 0 || renderHeight <= 0 || renderWidth > bounds.width() || renderHeight > bounds.height()) { + if (renderWidth <= 0 || renderHeight <= 0) { + Logger.warning("Skipping software rendering: transformed bounds have negative values."); + return; + } + + long renderPixelCount = (long) renderWidth * (long) renderHeight; + if (renderPixelCount > MAX_SOFTWARE_BITMAP_PIXELS) { + Logger.warning("Skipping software rendering: bitmap request exceeds safe pixel count (" + renderPixelCount + ")"); return; } @@ -1891,6 +1907,17 @@ src.bottom); } + private static boolean isFiniteRect(RectF rect) { + return isFinite(rect.left) && + isFinite(rect.top) && + isFinite(rect.right) && + isFinite(rect.bottom); + } + + private static boolean isFinite(float value) { + return !Float.isNaN(value) && !Float.isInfinite(value); + } + private void scaleRect(RectF rect, float scaleX, float scaleY) { rect.set( rect.left * scaleX,