Patch to fix memory access bug in TEXT_WordBreak

Robert O'Callahan robert at ocallahan.org
Mon Apr 22 18:18:01 CDT 2002


I found a bug in TEXT_WordBreak that was variously throwing Lotus Notes 
into an infinite loop or causing it to crash. The attached patch fixes 
the bug.

The problem occurs in DrawTextExW when a single-character, 
non-null-terminated string doesn't fit in the supplied width (in this 
case Notes is passing (0,0,0,0) as the rectangle and asking for 
DT_CALCRECT, but also passing DT_WORDBREAK ... that's probably a Notes 
bug, but it doesn't matter...) We call TEXT_WordBreak with chars_fit == 
0. The function sets word_fits because the first character didn't fit. 
We advance (p++) so as to break after that character. The original code 
then examines the NEXT character to see if it's a space and to absorb it 
if it is. Problem is of course there is no next character, it examines 
garbage and things can then go haywire. (In my case the next character 
happened to be a space so it absorbed an extra character, causing *count 
in TEXT_NextWordW to go negative and then all hell breaks loose.) The 
fix is simply to only absorb an extra space if we haven't already 
reached the end of the string.

Rob

-- 
Robert O'Callahan <robert at ocallahan.org>        http://ocallahan.org
"If we claim to be without sin, we deceive ourselves and the truth is
not in us. If we confess our sins, he is faithful and just and will
forgive us our sins and purify us from all unrighteousness."
   1 John 1:8-9

-------------- next part --------------
--- text.c.bak	Mon Apr 22 18:51:35 2002
+++ text.c	Mon Apr 22 18:58:53 2002
@@ -356,13 +356,15 @@
     /* If there was one or the first character didn't fit then */
     if (word_fits)
     {
+        int next_is_space;
         /* break the line before/after that character */
         if (!(format & (DT_RIGHT | DT_CENTER)) || *p != SPACE)
             p++;
+        next_is_space = (p - str) < *len_str && *p == SPACE;
         *len_str = p - str;
         /* and if the next character is a space then discard it. */
         *chars_used = *len_str;
-        if (*p == SPACE)
+        if (next_is_space)
             (*chars_used)++;
     }
     /* Suppose there was none. */


More information about the wine-patches mailing list