Commit 6f22b03151 for ffmpeg
commit 6f22b03151b83524623f148ca75b5a119301bdcd
Author: Niklas Haas <git@haasn.dev>
Date: Thu Oct 22 20:43:58 2026 +0200
checkasm/sw_ops: check for undeclared over-write
Use checkasm's own BUF_RECT() and padded buffer checking to get this
for almost free. The one major issue is that check_*_padded() assumes the
padding is a power of two alignment, which is not an assumption made by
libswscale.
Fix this by explicitly copying over the declared number of over-write bytes
from the reference buffer, before doing the check.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Niklas Haas <git@haasn.dev>
diff --git a/tests/checkasm/sw_ops.c b/tests/checkasm/sw_ops.c
index 39f05dd03a..0d17d8bd7d 100644
--- a/tests/checkasm/sw_ops.c
+++ b/tests/checkasm/sw_ops.c
@@ -158,8 +158,9 @@ static void check_compiled(const Test *test,
static DECLARE_ALIGNED_64(char, src0)[NB_PLANES][LINES][PIXELS * sizeof(uint32_t[4])];
static DECLARE_ALIGNED_64(char, src1)[NB_PLANES][LINES][PIXELS * sizeof(uint32_t[4])];
- static DECLARE_ALIGNED_64(char, dst0)[NB_PLANES][LINES][PIXELS * sizeof(uint32_t[4])];
- static DECLARE_ALIGNED_64(char, dst1)[NB_PLANES][LINES][PIXELS * sizeof(uint32_t[4])];
+ /* All output planes are stacked vertically in a single padded buffer */
+ static BUF_RECT(uint8_t, dst0, PIXELS * sizeof(uint32_t[4]), NB_PLANES * LINES);
+ static BUF_RECT(uint8_t, dst1, PIXELS * sizeof(uint32_t[4]), NB_PLANES * LINES);
av_assert0(PIXELS % comp_new->block_size == 0);
for (int p = 0; p < NB_PLANES; p++) {
@@ -186,8 +187,8 @@ static void check_compiled(const Test *test,
}
memcpy(src1, src0, sizeof(src0));
- memset(dst0, 0, sizeof(dst0));
- memset(dst1, 0, sizeof(dst1));
+ CLEAR_BUF_RECT(dst0);
+ CLEAR_BUF_RECT(dst1);
const int read_size = PIXELS * test->pixel_bits_in >> 3;
const int write_size = PIXELS * test->pixel_bits_out >> 3;
@@ -197,7 +198,7 @@ static void check_compiled(const Test *test,
exec.height = exec.slice_h = LINES;
for (int i = 0; i < NB_PLANES; i++) {
exec.in_stride[i] = sizeof(src0[i][0]);
- exec.out_stride[i] = sizeof(dst0[i][0]);
+ exec.out_stride[i] = dst0_stride;
exec.in_bump[i] = exec.in_stride[i] - read_size;
exec.out_bump[i] = exec.out_stride[i] - write_size;
}
@@ -228,7 +229,7 @@ static void check_compiled(const Test *test,
for (int i = 0; i < NB_PLANES; i++) {
exec.in[i] = (void *) src0[i];
- exec.out[i] = (void *) dst0[i];
+ exec.out[i] = dst0 + i * LINES * dst0_stride;
exec.block_size_in[i] = comp_ref->block_size * test->pixel_bits_in >> 3;
exec.block_size_out[i] = comp_ref->block_size * test->pixel_bits_out >> 3;
}
@@ -236,7 +237,7 @@ static void check_compiled(const Test *test,
for (int i = 0; i < NB_PLANES; i++) {
exec.in[i] = (void *) src1[i];
- exec.out[i] = (void *) dst1[i];
+ exec.out[i] = dst1 + i * LINES * dst1_stride;
exec.block_size_in[i] = comp_new->block_size * test->pixel_bits_in >> 3;
exec.block_size_out[i] = comp_new->block_size * test->pixel_bits_out >> 3;
}
@@ -246,28 +247,41 @@ static void check_compiled(const Test *test,
if (!SWS_COMP_TEST(test->planes_out, i))
continue;
+ /* checkasm_check_padded() assumes a power of two alignment, but our
+ * overwrite may be an arbitrary number of bytes. Smooth out the
+ * difference by manually copying over the padding from the reference
+ * to the output buffer, and extending the checked padding past it. */
+ const int elem_size = ff_sws_pixel_type_size(test->type_out);
+ const int over_write = comp_new->over_write[i];
+ const int padding = (over_write + elem_size - 1) / elem_size + 8;
+ const int w = write_size / elem_size;
+ const uint8_t *out_ref = dst0 + i * LINES * dst0_stride;
+ uint8_t *out_new = exec.out[i];
+ for (int y = 0; y < LINES; y++) {
+ memcpy(&out_new[y * dst1_stride + write_size],
+ &out_ref[y * dst0_stride + write_size], over_write);
+ }
+
const char *desc = FMT("%s[%d]", test->name, i);
- const int stride = sizeof(dst0[i][0]);
switch (test->type_out) {
case SWS_PIXEL_U8:
- checkasm_check(uint8_t, (void *) dst0[i], stride,
- (void *) dst1[i], stride,
- write_size, LINES, desc);
+ checkasm_check_padded(uint8_t, out_ref, dst0_stride, out_new, dst1_stride,
+ w, LINES, desc, 1, 0, padding);
break;
case SWS_PIXEL_U16:
- checkasm_check(uint16_t, (void *) dst0[i], stride,
- (void *) dst1[i], stride,
- write_size >> 1, LINES, desc);
+ checkasm_check_padded(uint16_t, (void *) out_ref, dst0_stride,
+ (void *) out_new, dst1_stride,
+ w, LINES, desc, 1, 0, padding);
break;
case SWS_PIXEL_U32:
- checkasm_check(uint32_t, (void *) dst0[i], stride,
- (void *) dst1[i], stride,
- write_size >> 2, LINES, desc);
+ checkasm_check_padded(uint32_t, (void *) out_ref, dst0_stride,
+ (void *) out_new, dst1_stride,
+ w, LINES, desc, 1, 0, padding);
break;
case SWS_PIXEL_F32:
- checkasm_check(float_ulp, (void *) dst0[i], stride,
- (void *) dst1[i], stride,
- write_size >> 2, LINES, desc, 0);
+ checkasm_check_padded(float_ulp, (void *) out_ref, dst0_stride,
+ (void *) out_new, dst1_stride,
+ w, LINES, desc, 0, 1, 0, padding);
break;
}
}