Text handling broke.

Dmitry Timoshkov dmitry at news.sloboda.ru
Sun Feb 4 20:05:19 CST 2001


"Duane" <junkmail at junkmail.com> wrote:

> As mentioned elsewhere, I did try this patch, but still had the problem.
> So I stuck a couple of trace messages into EDIT_EM_GetLine() and ran the
> program some more. I entering a string of four characters into the text
> dialog, and found that EDIT_EM_GetLine() was entered with the unicode
> boolean set, EDIT_EM_LineLength returned four and set len accordingly,
> and then the for loop was entered and four characters were copied from
> src to lpch.
> 
> Under the theory (which I have no idea whether it is right) that I also
> needed to copy the terminating '\0', I changed the loop termination test
> from 
>   i < len
> to
>   i <= len
> 
> So that for my 4 character string, it would copy 5 characters. And that
> seems to have worked, at least in my case, though I have no idea whether
> that might impact something else.

This is could easy overwrite some data in your program, if the passed
buffer is not large enough.

Please try the attached patch, it should solve your problem.

-------------- next part --------------
--- cvs/wine/controls/edit.c	Sat Jan 27 16:26:14 2001
+++ wine/controls/edit.c	Mon Feb  5 09:56:37 2001
@@ -204,7 +204,7 @@
 static BOOL	EDIT_EM_FmtLines(EDITSTATE *es, BOOL add_eol);
 static HLOCAL	EDIT_EM_GetHandle(EDITSTATE *es);
 static HLOCAL16	EDIT_EM_GetHandle16(WND *wnd, EDITSTATE *es);
-static INT	EDIT_EM_GetLine(EDITSTATE *es, INT line, LPWSTR lpch);
+static INT	EDIT_EM_GetLine(EDITSTATE *es, INT line, LPARAM lParam, BOOL unicode);
 static LRESULT	EDIT_EM_GetSel(EDITSTATE *es, LPUINT start, LPUINT end);
 static LRESULT	EDIT_EM_GetThumb(WND *wnd, EDITSTATE *es);
 static INT	EDIT_EM_LineFromChar(EDITSTATE *es, INT index);
@@ -661,7 +661,7 @@
 		/* fall through */
 	case EM_GETLINE:
 		DPRINTF_EDIT_MSG32("EM_GETLINE");
-		result = (LRESULT)EDIT_EM_GetLine(es, (INT)wParam, (LPWSTR)lParam);
+		result = (LRESULT)EDIT_EM_GetLine(es, (INT)wParam, lParam, unicode);
 		break;
 
 	case EM_LIMITTEXT16:
@@ -2501,10 +2501,10 @@
  *	EM_GETLINE
  *
  */
-static INT EDIT_EM_GetLine(EDITSTATE *es, INT line, LPWSTR lpch)
+static INT EDIT_EM_GetLine(EDITSTATE *es, INT line, LPARAM lParam, BOOL unicode)
 {
 	LPWSTR src;
-	INT len;
+	INT line_len, dst_len;
 	INT i;
 
 	if (es->style & ES_MULTILINE) {
@@ -2514,13 +2514,34 @@
 		line = 0;
 	i = EDIT_EM_LineIndex(es, line);
 	src = es->text + i;
-	len = min(*(WORD *)lpch, EDIT_EM_LineLength(es, i));
-	for (i = 0 ; i < len ; i++) {
-		*lpch = *src;
-		src++;
-		lpch++;
+	line_len = EDIT_EM_LineLength(es, i);
+	dst_len = *(WORD *)lParam;
+	if(unicode)
+	{
+	    LPWSTR dst = (LPWSTR)lParam;
+	    if(dst_len < line_len)
+	    {
+		memcpy(dst, src, dst_len * sizeof(WCHAR));
+		return dst_len;
+	    }
+	    else /* Append 0 if enough space */
+	    {
+		memcpy(dst, src, line_len * sizeof(WCHAR));
+		dst[line_len] = 0;
+		return line_len;
+	    }
+	}
+	else
+	{
+	    LPSTR dst = (LPSTR)lParam;
+	    INT ret;
+	    ret = WideCharToMultiByte(CP_ACP, 0, src, line_len, dst, dst_len, NULL, NULL);
+	    if(!ret) /* Insufficient buffer size */
+		return dst_len;
+	    if(ret < dst_len) /* Append 0 if enough space */
+		dst[ret] = 0;
+	    return ret;
 	}
-	return (LRESULT)len;
 }
 
 


More information about the wine-users mailing list