[PATCH] Change memcpy to memmove in fbBlt

Matt Turner mattst88 at gmail.com
Wed May 30 08:43:35 PDT 2012


On Wed, May 30, 2012 at 10:23 AM, Michal Srb <msrb at suse.com> wrote:
> 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

We had a similar patch in a Gentoo overlay but without any description
of why it's needed. Knowing now what its purpose is,

Acked-by: Matt Turner <mattst88 at gmail.com>

Although, I'm surprised there isn't a bug link or similar attached to
this patch. If it can lead to graphical artifacts, surely we'd have
some reports.


More information about the xorg-devel mailing list