aom: av1_compute_stats_sve: add missing height check

From a0f61021becd361837e07a0dc943f78da5cac39a Mon Sep 17 00:00:00 2001
From: James Zern <[EMAIL REDACTED]>
Date: Thu, 30 May 2024 16:28:54 -0700
Subject: [PATCH] av1_compute_stats_sve: add missing height check

downsample_height may be 0; compute_stats_win7_sve and
compute_stats_win5_sve assume it is at least 1. This fixes a crash with
heights < downsample_factor as exhibited by
SearchWienerTest.8bitSignedIntegerOverflowInLinsolveWiener. The checks
align with those in av1_compute_stats_neon().

Change-Id: Ia3c8210816a71213640a79c84714c5ae8d2ee1a9
---
 av1/encoder/arm/pickrst_sve.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/av1/encoder/arm/pickrst_sve.c b/av1/encoder/arm/pickrst_sve.c
index e865dadd4..5d7370b5d 100644
--- a/av1/encoder/arm/pickrst_sve.c
+++ b/av1/encoder/arm/pickrst_sve.c
@@ -11,6 +11,7 @@
 
 #include <arm_neon.h>
 #include <arm_sve.h>
+#include <assert.h>
 #include <string.h>
 
 #include "config/aom_config.h"
@@ -159,6 +160,7 @@ static INLINE void compute_stats_win7_sve(int16_t *dgd_avg, int dgd_avg_stride,
   int64_t H_tmp[49 * 49];
   memset(H_tmp, 0, sizeof(H_tmp));
 
+  assert(height > 0);
   do {
     // Cross-correlation (M).
     for (int row = 0; row < wiener_win; row++) {
@@ -292,6 +294,7 @@ static INLINE void compute_stats_win5_sve(int16_t *dgd_avg, int dgd_avg_stride,
   int64_t H_tmp[25 * 25];
   memset(H_tmp, 0, sizeof(H_tmp));
 
+  assert(height > 0);
   do {
     // Cross-correlation (M).
     for (int row = 0; row < wiener_win; row++) {
@@ -435,12 +438,14 @@ void av1_compute_stats_sve(int wiener_win, const uint8_t *dgd,
   // the last line of src will be scaled according to how many rows remain.
   const int downsample_remainder = height % downsample_factor;
 
-  if (wiener_win == WIENER_WIN) {
-    compute_stats_win7_sve(dgd_avg, dgd_avg_stride, src_avg, src_avg_stride,
-                           width, downsample_height, M, H, downsample_factor);
-  } else {
-    compute_stats_win5_sve(dgd_avg, dgd_avg_stride, src_avg, src_avg_stride,
-                           width, downsample_height, M, H, downsample_factor);
+  if (downsample_height > 0) {
+    if (wiener_win == WIENER_WIN) {
+      compute_stats_win7_sve(dgd_avg, dgd_avg_stride, src_avg, src_avg_stride,
+                             width, downsample_height, M, H, downsample_factor);
+    } else {
+      compute_stats_win5_sve(dgd_avg, dgd_avg_stride, src_avg, src_avg_stride,
+                             width, downsample_height, M, H, downsample_factor);
+    }
   }
 
   if (downsample_remainder > 0) {