aboutsummaryrefslogtreecommitdiffstats
path: root/tests/checkasm/checkasm.c
diff options
context:
space:
mode:
authorMartin Storsjö <martin@martin.st>2025-03-22 00:49:47 +0200
committerMartin Storsjö <martin@martin.st>2025-04-01 18:34:51 +0300
commitb863b81500f374a2829e9dfb3a244c61e3fc1a60 (patch)
treeac2c1a0bdbf7e94cf1e5c22f1b2919c4c7eb02d7 /tests/checkasm/checkasm.c
parent37c664a2533b2c53beda450899c1a06ac37637ec (diff)
downloadffmpeg-b863b81500f374a2829e9dfb3a244c61e3fc1a60.tar.gz
checkasm: Implement helpers for defining and checking padded rects
This backports similar functionality from dav1d, from commits 35d1d011fda4a92bcaf42d30ed137583b27d7f6d and d130da9c315d5a1d3968d278bbee2238ad9051e7. This allows detecting writes out of bounds, on all 4 sides of the intended destination rectangle. The bounds checking also can optionally allow small overwrites (up to a specified alignment), while still checking for larger overwrites past the intended allowed region. Signed-off-by: Martin Storsjö <martin@martin.st>
Diffstat (limited to 'tests/checkasm/checkasm.c')
-rw-r--r--tests/checkasm/checkasm.c89
1 files changed, 70 insertions, 19 deletions
diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c
index c6d641c52b..a5b862fe52 100644
--- a/tests/checkasm/checkasm.c
+++ b/tests/checkasm/checkasm.c
@@ -1168,37 +1168,88 @@ void checkasm_report(const char *name, ...)
}
}
+static int check_err(const char *file, int line,
+ const char *name, int w, int h,
+ int *err)
+{
+ if (*err)
+ return 0;
+ if (!checkasm_fail_func("%s:%d", file, line))
+ return 1;
+ *err = 1;
+ fprintf(stderr, "%s (%dx%d):\n", name, w, h);
+ return 0;
+}
+
#define DEF_CHECKASM_CHECK_FUNC(type, fmt) \
int checkasm_check_##type(const char *file, int line, \
const type *buf1, ptrdiff_t stride1, \
const type *buf2, ptrdiff_t stride2, \
- int w, int h, const char *name) \
+ int w, int h, const char *name, \
+ int align_w, int align_h, \
+ int padding) \
{ \
+ int aligned_w = (w + align_w - 1) & ~(align_w - 1); \
+ int aligned_h = (h + align_h - 1) & ~(align_h - 1); \
+ int err = 0; \
int y = 0; \
stride1 /= sizeof(*buf1); \
stride2 /= sizeof(*buf2); \
for (y = 0; y < h; y++) \
if (memcmp(&buf1[y*stride1], &buf2[y*stride2], w*sizeof(*buf1))) \
break; \
- if (y == h) \
- return 0; \
- if (!checkasm_fail_func("%s:%d", file, line)) \
- return 1; \
- fprintf(stderr, "%s:\n", name); \
- while (h--) { \
- for (int x = 0; x < w; x++) \
- fprintf(stderr, " " fmt, buf1[x]); \
- fprintf(stderr, " "); \
- for (int x = 0; x < w; x++) \
- fprintf(stderr, " " fmt, buf2[x]); \
- fprintf(stderr, " "); \
- for (int x = 0; x < w; x++) \
- fprintf(stderr, "%c", buf1[x] != buf2[x] ? 'x' : '.'); \
- buf1 += stride1; \
- buf2 += stride2; \
- fprintf(stderr, "\n"); \
+ if (y != h) { \
+ if (check_err(file, line, name, w, h, &err)) \
+ return 1; \
+ for (y = 0; y < h; y++) { \
+ for (int x = 0; x < w; x++) \
+ fprintf(stderr, " " fmt, buf1[x]); \
+ fprintf(stderr, " "); \
+ for (int x = 0; x < w; x++) \
+ fprintf(stderr, " " fmt, buf2[x]); \
+ fprintf(stderr, " "); \
+ for (int x = 0; x < w; x++) \
+ fprintf(stderr, "%c", buf1[x] != buf2[x] ? 'x' : '.'); \
+ buf1 += stride1; \
+ buf2 += stride2; \
+ fprintf(stderr, "\n"); \
+ } \
+ buf1 -= h*stride1; \
+ buf2 -= h*stride2; \
} \
- return 1; \
+ for (y = -padding; y < 0; y++) \
+ if (memcmp(&buf1[y*stride1 - padding], &buf2[y*stride2 - padding], \
+ (w + 2*padding)*sizeof(*buf1))) { \
+ if (check_err(file, line, name, w, h, &err)) \
+ return 1; \
+ fprintf(stderr, " overwrite above\n"); \
+ break; \
+ } \
+ for (y = aligned_h; y < aligned_h + padding; y++) \
+ if (memcmp(&buf1[y*stride1 - padding], &buf2[y*stride2 - padding], \
+ (w + 2*padding)*sizeof(*buf1))) { \
+ if (check_err(file, line, name, w, h, &err)) \
+ return 1; \
+ fprintf(stderr, " overwrite below\n"); \
+ break; \
+ } \
+ for (y = 0; y < h; y++) \
+ if (memcmp(&buf1[y*stride1 - padding], &buf2[y*stride2 - padding], \
+ padding*sizeof(*buf1))) { \
+ if (check_err(file, line, name, w, h, &err)) \
+ return 1; \
+ fprintf(stderr, " overwrite left\n"); \
+ break; \
+ } \
+ for (y = 0; y < h; y++) \
+ if (memcmp(&buf1[y*stride1 + aligned_w], &buf2[y*stride2 + aligned_w], \
+ padding*sizeof(*buf1))) { \
+ if (check_err(file, line, name, w, h, &err)) \
+ return 1; \
+ fprintf(stderr, " overwrite right\n"); \
+ break; \
+ } \
+ return err; \
}
DEF_CHECKASM_CHECK_FUNC(uint8_t, "%02x")