[ddraw] Fix bug 3487 take 2

Christian Costa titan.costa at wanadoo.fr
Sun Oct 9 17:46:45 CDT 2005


Peter Berg Larsen wrote:

>
> Walking backwards the bug was introduced in
>
> http://www.winehq.org/pipermail/wine-patches/2002-November/004161.html
>
> and altered in
>
> http://www.winehq.org/pipermail/wine-patches/2004-March/010091.html
>
> which states
>
>> Apps should initialize correctly the dwSize member of ddraw structures.
>> However some of them do not do this and Windows seems to handle that
>> case without crashing.
>> Here is a patch that prevents clearing more that the struct size.
>> This fixes the bug 2070.
>
>
> So here is better patch that does not open 2070 again.
>
>
> Changelog:
>         Bug in copying structs if to == from as to was memset first.
>
> diff -u Wine-20050930/dlls/ddraw/ddraw_private.h 
> Wine-20050930my/dlls/ddraw/ddraw_private.h
> --- Wine-20050930/dlls/ddraw/ddraw_private.h    2005-07-24 
> 18:17:29.000000000 +0200
> +++ Wine-20050930my/dlls/ddraw/ddraw_private.h    2005-10-09 
> 04:50:59.000000000 +0200
> @@ -41,18 +41,22 @@
>          (x)->dwSize = sizeof(*x);    \
>      } while (0)
>
> +/* __tosize can be set too large by some programs */
>  #define DD_STRUCT_COPY_BYSIZE(to,from)            \
>      do {                        \
> -            DWORD __size = (to)->dwSize;        \
> -            DWORD __copysize = __size;        \
> -            DWORD __resetsize = __size;        \
> -            if (__resetsize > sizeof(*to))        \
> -            __resetsize = sizeof(*to);        \
> -            memset(to,0,__resetsize);               \
> -            if ((from)->dwSize < __size)         \
> -            __copysize = (from)->dwSize;    \
> -        memcpy(to,from,__copysize);        \
> -        (to)->dwSize = __size;/*restore size*/    \
> +        DWORD __tosize = (to)->dwSize;        \
> +        DWORD __fromsize = (from)->dwSize;    \
> +        if ((to) == (from))            \
> +            break;                \
> +        if (__tosize > sizeof(*(to)))        \
> +            ERR("To struct's size too large");    \
> +        if (__fromsize > sizeof(*(from)))    \
> +            ERR("From struct's size too large");\
> +        if (__fromsize > __tosize)        \
> +            ERR("Copying too large struct");    \
> +        memcpy(to,from,__fromsize);        \
> +        memset(to+__fromsize,0,sizeof(*(to))-__fromsize);    \
> +        (to)->dwSize = __tosize;/*restore size*/\
>      } while (0)
>
>  #define MAKE_FOURCC(a,b,c,d) ((a << 0) | (b << 8) | (c << 16) | (d << 
> 24))
>
>
>
>
This does not work if the destination size is smaller than the struct 
size or source size is greater than destination size.
Even worst, if source size is greater than struct size, 
sizeof(*(to))-__fromsize is < 0.
Why don't you just add the "if (to = from) break;" statement ?

Christian







More information about the wine-devel mailing list