From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <ffmpeg-devel-bounces@ffmpeg.org>
Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100])
	by master.gitmailbox.com (Postfix) with ESMTPS id CC2AF4B555
	for <ffmpegdev@gitmailbox.com>; Wed, 26 Mar 2025 10:30:41 +0000 (UTC)
Received: from [127.0.1.1] (localhost [127.0.0.1])
	by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 3F0CA687B9C;
	Wed, 26 Mar 2025 12:30:26 +0200 (EET)
Received: from mail-lf1-f46.google.com (mail-lf1-f46.google.com
 [209.85.167.46])
 by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 66222687B70
 for <ffmpeg-devel@ffmpeg.org>; Wed, 26 Mar 2025 12:30:18 +0200 (EET)
Received: by mail-lf1-f46.google.com with SMTP id
 2adb3069b0e04-5499d2134e8so7813263e87.0
 for <ffmpeg-devel@ffmpeg.org>; Wed, 26 Mar 2025 03:30:18 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=martin-st.20230601.gappssmtp.com; s=20230601; t=1742985017; x=1743589817;
 darn=ffmpeg.org; 
 h=content-transfer-encoding:mime-version:references:in-reply-to
 :message-id:date:subject:to:from:from:to:cc:subject:date:message-id
 :reply-to; bh=d05C7fOt2SKauR8fzfQeaSjiy8+w1Qz6uK+3qCuQnZ4=;
 b=ZB80C+az0PJ4gLreh/mIoB+XBstjqqVZOYJaz1fvn1TEOMzBoTs3YGIeuMF+QtJz5h
 M0SIhemVOgQqV2/64Z2QLRHdtlCqY52qYVeai7s5vYB3h/enNRp/b0M55S+SvhyuCjQ+
 L18ALBlV3IMIDatcMvE+Lyzl3MiA1eDhwArrzcj4S6mQ43vfSe+5mhJwbq8EHGOpr1LB
 OaTd6IVU3pRjLbdV5zT+/VcYdUoQBbRGQbZGGQeSzt3bg7UapTdEcKysssZjZz+EB9s6
 5nFRABtVF9jbu/Rm0M/ok1Xxdf6HEFbzpzgVcXdJbCPssUn3THL3Bzft3UtHQgd4VCqn
 xVJw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1742985017; x=1743589817;
 h=content-transfer-encoding:mime-version:references:in-reply-to
 :message-id:date:subject:to:from:x-gm-message-state:from:to:cc
 :subject:date:message-id:reply-to;
 bh=d05C7fOt2SKauR8fzfQeaSjiy8+w1Qz6uK+3qCuQnZ4=;
 b=pr14SZXz96nps/4IsFyuD9a1lnJCTRDyUHM4udGXlh3loFlxHofvf07AHVn0rovMw8
 0+GqNXMb19syIEhHPckfNCmbfxKtpchoLieHNlgMd/VUZu+7d3xIIx+nVrBHGeTKwTKd
 hxe4gueMsxVZ3H0z7ae6b4cjLIyD1dR9ymXAunEFF8gtF2q8VYPh29S/gEzGxF1zb8gs
 qJ6lGzQjUxqtpvxxsSV3IEtfz0LBRx78iXtc3EufvUk8Bl58o7Dzc9c4H+5uueg9VnF2
 4Lkv7qVoYOUTyX+PNw4n0Ndr/LrYxspH5EjwMOia/pD4tR33ylQ35GHtjHHw8kipV7yp
 hDkw==
X-Gm-Message-State: AOJu0YyHNedA+an7CK7eJbQMl67Stygmd9aLhw8zy9MT6SzQzGHiLo+C
 YMPBiLUKMihYBlCK2fA467RL0a6qVfCRdVPGIQ5DS+1kfl9Mo/l1T7nUfXHlKXN7iZeN/cBDrX6
 1VQ==
X-Gm-Gg: ASbGncsP0R/i6LlNSk40tgnS3d1GLIez86Ylh+FuomM3veCqHcBfDPudcnpD5w3XoUv
 cgpaI+Ff9s0kXU51mLKmvSbUWsDF9nEOAtIlum2Yih/AEkq2C/y7c36Zw/fKVLwG7XoOJEg3D8w
 JeHZIJaIylLcLkxgOSYAuutflXtquQcEmilVXMWYZx8WbNHCxqv8f6F8PVn1FOb7VqFBGfr3gdP
 ANayPEp9O3KGcjpA46t+WN8DMIkNxsQMefwSaLEyDMCcIoP6qs7cYgA+6a2idfDVLg+8JckYH2t
 aaC6IPG3cSyiV1JsnYGMx4b9C/2wqdIZjTPBazGgTTXjYt8xKjcvEMJlHx1FT+0Fdh7HfLHbkx0
 6k6BrE3aihJJ4wHVKsVthPA==
X-Google-Smtp-Source: AGHT+IGgKRZy7yCxgpAY9ZIqm2BlvdSAgkwCyNeB+1WLX6m7pgBTQDyxyldaisCBcyKPfle8Of87sw==
X-Received: by 2002:ac2:4e04:0:b0:549:5989:bb89 with SMTP id
 2adb3069b0e04-54ad64ef3bbmr7326066e87.35.1742985017386; 
 Wed, 26 Mar 2025 03:30:17 -0700 (PDT)
Received: from localhost (dsl-tkubng21-50de30-198.dhcp.inet.fi.
 [80.222.48.198]) by smtp.gmail.com with ESMTPSA id
 2adb3069b0e04-54affe6b83bsm3721e87.151.2025.03.26.03.30.17
 for <ffmpeg-devel@ffmpeg.org>
 (version=TLS1 cipher=AES128-SHA bits=128/128);
 Wed, 26 Mar 2025 03:30:17 -0700 (PDT)
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin@martin.st>
To: ffmpeg-devel@ffmpeg.org
Date: Wed, 26 Mar 2025 12:30:13 +0200
Message-Id: <20250326103015.44296-2-martin@martin.st>
X-Mailer: git-send-email 2.39.5 (Apple Git-154)
In-Reply-To: <20250326103015.44296-1-martin@martin.st>
References: <20250326103015.44296-1-martin@martin.st>
MIME-Version: 1.0
Subject: [FFmpeg-devel] [PATCH 2/4] checkasm: Implement helpers for defining
 and checking padded rects
X-BeenThere: ffmpeg-devel@ffmpeg.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: FFmpeg development discussions and patches <ffmpeg-devel.ffmpeg.org>
List-Unsubscribe: <https://ffmpeg.org/mailman/options/ffmpeg-devel>,
 <mailto:ffmpeg-devel-request@ffmpeg.org?subject=unsubscribe>
List-Archive: <https://ffmpeg.org/pipermail/ffmpeg-devel>
List-Post: <mailto:ffmpeg-devel@ffmpeg.org>
List-Help: <mailto:ffmpeg-devel-request@ffmpeg.org?subject=help>
List-Subscribe: <https://ffmpeg.org/mailman/listinfo/ffmpeg-devel>,
 <mailto:ffmpeg-devel-request@ffmpeg.org?subject=subscribe>
Reply-To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org>
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Errors-To: ffmpeg-devel-bounces@ffmpeg.org
Sender: "ffmpeg-devel" <ffmpeg-devel-bounces@ffmpeg.org>
Archived-At: <https://master.gitmailbox.com/ffmpegdev/20250326103015.44296-2-martin@martin.st/>
List-Archive: <https://master.gitmailbox.com/ffmpegdev/>
List-Post: <mailto:ffmpegdev@gitmailbox.com>

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.
---
 tests/checkasm/checkasm.c | 89 ++++++++++++++++++++++++++++++---------
 tests/checkasm/checkasm.h | 55 ++++++++++++++++++++----
 2 files changed, 116 insertions(+), 28 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")
diff --git a/tests/checkasm/checkasm.h b/tests/checkasm/checkasm.h
index 852d6fca64..ca7cfac3f7 100644
--- a/tests/checkasm/checkasm.h
+++ b/tests/checkasm/checkasm.h
@@ -375,11 +375,30 @@ typedef struct CheckasmPerf {
 #define PERF_STOP(t)   while(0)
 #endif
 
+#define BUF_RECT(type, name, w, h) \
+    LOCAL_ALIGNED_32(type, name##_buf, [((h)+32)*(FFALIGN(w,64)+64) + 64]); \
+    av_unused ptrdiff_t name##_stride = sizeof(type)*(FFALIGN(w,64)+64); \
+    av_unused int name##_buf_h = (h)+32; \
+    type *name = name##_buf + (FFALIGN(w,64)+64)*16 + 64
+
+#define PIXEL_RECT(name, w, h) \
+    LOCAL_ALIGNED_32(uint8_t, name##_buf, [sizeof(uint16_t) * (((h)+32)*(FFALIGN(w,64)+64) + 64)],); \
+    av_unused ptrdiff_t name##_stride = sizeof(uint16_t) * (FFALIGN(w,64)+64); \
+    av_unused int name##_buf_h = (h)+32; \
+    uint8_t *name = name##_buf + (FFALIGN(w,64)+64)*16 + 64
+
+#define CLEAR_BUF_RECT(name) \
+    memset(name##_buf, 0x99, name##_stride * name##_buf_h + 64)
+#define CLEAR_PIXEL_RECT(name) \
+    CLEAR_BUF_RECT(name)
+
 #define DECL_CHECKASM_CHECK_FUNC(type) \
 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)
 
 DECL_CHECKASM_CHECK_FUNC(uint8_t);
 DECL_CHECKASM_CHECK_FUNC(uint16_t);
@@ -390,18 +409,36 @@ DECL_CHECKASM_CHECK_FUNC(int32_t);
 #define PASTE(a,b) a ## b
 #define CONCAT(a,b) PASTE(a,b)
 
-#define checkasm_check(prefix, ...) CONCAT(checkasm_check_, prefix)(__FILE__, __LINE__, __VA_ARGS__)
+#define checkasm_check2(prefix, ...) CONCAT(checkasm_check_, prefix)(__FILE__, __LINE__, __VA_ARGS__)
+#define checkasm_check(prefix, ...) checkasm_check2(prefix, __VA_ARGS__, 0, 0, 0)
+/* Check a pointer from BUF_RECT, checking whether there have been
+ * writes outside of the designated area. */
+#define checkasm_check_padded(...) \
+    checkasm_check2(__VA_ARGS__, 1, 1, 8)
+/* Check a pointer from BUF_RECT, checking whether there have been
+ * writes outside of the designated area. Allow writing slightly past the
+ * end of the buffer, by aligning w/h to align_w/align_h, and checking
+ * for overwrites outside of that. */
+#define checkasm_check_padded_align(...) \
+    checkasm_check2(__VA_ARGS__, 8)
 
 /* This assumes that there is a local variable named "bit_depth".
  * For tests that don't have that and only operate on a single
  * bitdepth, just call checkasm_check(uint8_t, ...) directly. */
-#define checkasm_check_pixel(buf1, stride1, buf2, stride2, ...) \
+#define checkasm_check_pixel2(buf1, stride1, buf2, stride2, ...) \
     ((bit_depth > 8) ?                                          \
-     checkasm_check(uint16_t, (const uint16_t*)buf1, stride1,   \
-                              (const uint16_t*)buf2, stride2,   \
-                              __VA_ARGS__) :                    \
-     checkasm_check(uint8_t,  (const uint8_t*) buf1, stride1,   \
-                              (const uint8_t*) buf2, stride2,   \
-                              __VA_ARGS__))
+     checkasm_check2(uint16_t, (const uint16_t*)buf1, stride1,   \
+                               (const uint16_t*)buf2, stride2,   \
+                               __VA_ARGS__) :                    \
+     checkasm_check2(uint8_t,  (const uint8_t*) buf1, stride1,   \
+                               (const uint8_t*) buf2, stride2,   \
+                               __VA_ARGS__))
+#define checkasm_check_pixel(...) \
+    checkasm_check_pixel2(__VA_ARGS__, 0, 0, 0)
+#define checkasm_check_pixel_padded(...) \
+    checkasm_check_pixel2(__VA_ARGS__, 1, 1, 8)
+#define checkasm_check_pixel_padded_align(...) \
+    checkasm_check_pixel2(__VA_ARGS__, 8)
+
 
 #endif /* TESTS_CHECKASM_CHECKASM_H */
-- 
2.39.5 (Apple Git-154)

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".