[PATCH] Change memcpy to memmove in fbBlt

Michal Srb msrb at suse.com
Wed May 30 07:23:10 PDT 2012


In case of horizontal blitting of less than width of blitted area,
memcpy is used on overlapping areas which is not allowed. The behavior
is undefined in such case, probably leading to graphical artifact when
blitting in specific direction.
---
 fb/fb.h    |   14 ++++++++++----
 fb/fbblt.c |    4 ++--
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/fb/fb.h b/fb/fb.h
index b327ce6..b4f2ffd 100644
--- a/fb/fb.h
+++ b/fb/fb.h
@@ -49,11 +49,17 @@
 #define WRITE(ptr, val) ((*wfbWriteMemory)((ptr), (val), sizeof(*(ptr))))
 #define READ(ptr) ((*wfbReadMemory)((ptr), sizeof(*(ptr))))
 
-#define MEMCPY_WRAPPED(dst, src, size) do {                       \
+#define MEMMOVE_WRAPPED(dst, src, size) do {                      \
     size_t _i;                                                    \
     CARD8 *_dst = (CARD8*)(dst), *_src = (CARD8*)(src);           \
-    for(_i = 0; _i < size; _i++) {                                \
-        WRITE(_dst +_i, READ(_src + _i));                         \
+    if(_src < _dst) {                                             \
+        for(_i = 0; _i < size; _i++) {                            \
+            WRITE(_dst +_i, READ(_src + _i));                     \
+        }                                                         \
+    } else {                                                      \
+        for(_i = 0; _i < size; _i++) {                            \
+            WRITE(_dst + size - _i - 1, READ(_src + size - _i - 1)); \
+        }                                                         \
     }                                                             \
 } while(0)
 
@@ -70,7 +76,7 @@
 #define FBPREFIX(x) fb##x
 #define WRITE(ptr, val) (*(ptr) = (val))
 #define READ(ptr) (*(ptr))
-#define MEMCPY_WRAPPED(dst, src, size) memcpy((dst), (src), (size))
+#define MEMMOVE_WRAPPED(dst, src, size) memmove((dst), (src), (size))
 #define MEMSET_WRAPPED(dst, val, size) memset((dst), (val), (size))
 
 #endif
diff --git a/fb/fbblt.c b/fb/fbblt.c
index 17bd698..b4dfeb7 100644
--- a/fb/fbblt.c
+++ b/fb/fbblt.c
@@ -84,10 +84,10 @@ fbBlt(FbBits * srcLine,
 
         if (!upsidedown)
             for (i = 0; i < height; i++)
-                MEMCPY_WRAPPED(dst + i * dstStride, src + i * srcStride, width);
+                MEMMOVE_WRAPPED(dst + i * dstStride, src + i * srcStride, width);
         else
             for (i = height - 1; i >= 0; i--)
-                MEMCPY_WRAPPED(dst + i * dstStride, src + i * srcStride, width);
+                MEMMOVE_WRAPPED(dst + i * dstStride, src + i * srcStride, width);
 
         return;
     }
-- 
1.7.7




More information about the xorg-devel mailing list