[Bug 13319] In dlls/user32/edit.c EDIT_EM_ReplaceSel Clobbers Important Var When Buffer Overflows

wine-bugs at winehq.org wine-bugs at winehq.org
Wed May 28 20:06:30 CDT 2008


http://bugs.winehq.org/show_bug.cgi?id=13319





--- Comment #4 from Luke Bratch <l_bratch at yahoo.co.uk>  2008-05-28 20:06:29 ---
Bob, please do not reply to wine-bugs, post in Bugzilla instead.  Email read:

"Attached is a C file which should demonstrate the problem.  You'll need to
adapt it to your environment as I use EDIT.C standalone.  In particular, you'll
need to change the value of LECWNDCLASS to the correct class name.

Perhaps the best way to see what's happening is to insert lines into the EDIT.C
function EDIT_EM_ReplaceSel:

Just before the lines

for (i = 0 , p = es->text + s ; i < strl ; i++)
     p[i] = lpsz_replace[i];

insert the lines

if (strl > strlenW (lpsz_replace))
    MessageBoxW (es->hwndParent,
                 L"Indexing out of bounds",
                 L"EDIT_EM_ReplaceSel",
                 MB_OK | MB_ICONEXCLAMATION);

Obviously, when strl retains its original value of strlenW(lpsz_replace), the
FOR loop indexes lpsz_replace from start to finish.  Thus, if the MessageBoxW
statement triggers, we're about to index lpsz_replace beyond its bounds.

-----------------------------------------------------

On related point, when the buffer overflows, the parent gets one shot to set
new limits.  Moreover, it might have no way of knowing how close it is to the
buffer limit, so it's hard to decide by how much the limit should be increased.
 It occurred to me that a small change in the code could resolve this problem:

Just after the line

if ((honor_limit) && (size > es->buffer_limit)) {

replace the call to EDIT_NOTIFY_PARENT(es, EN_MAXTEXT); with

    while (size > es->buffer_limit) {
        UINT oldLimit = es->buffer_limit;
        EDIT_NOTIFY_PARENT(es, EN_MAXTEXT);
        // If the new limit didn't increase, don't try again
        if (oldLimit >= es->buffer_limit)
            break;
    }

This way, the caller gets notified until the buffer limit is big enough or the
buffer limit doesn't change.

-----------------------------------------------------

FWIW, in EDIT.C I also found three typos/bugs.

#1:

old

ExStyle = GetWindowLongPtrW(es->hwndSelf, GWL_EXSTYLE);

new

ExStyle = GetWindowLongW(es->hwndSelf, GWL_EXSTYLE);

That is, GWL_EXSTYLE is a long, not a long ptr.

#2:

old

hBrush = (HBRUSH) GetClassLongW (es->hwndSelf, GCL_HBRBACKGROUND);

new

hBrush = (HBRUSH) GetClassLongPtrW (es->hwndSelf, GCL_HBRBACKGROUND);

That is, GCL_HBACKGROUND is a ptr, not a long.

#3:

old

MAKEWPARAM(GetWindowLongPtrW((es->hwndSelf),GWLP_ID), wNotifyCode), \

new

MAKEWPARAM(GetWindowLongW((es->hwndSelf),GWLP_ID), wNotifyCode), \

I thought that the GWL_ID was an integer (although it often is cast with
(HMENU)).  Nonetheless, MAKEWPARAM is expecting two four-byte values.
Under _WIN64, the difference is important."


-- 
Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email
Do not reply to this email, post in Bugzilla using the
above URL to reply.
------- You are receiving this mail because: -------
You are watching all bug changes.



More information about the wine-bugs mailing list