Alex Villacís Lasso : richedit: EM_LINELENGTH: honor CR and LF counters.
Alexandre Julliard
julliard at winehq.org
Tue Apr 29 08:54:45 CDT 2008
Module: wine
Branch: master
Commit: d95cbeef671186421da94a585d6201e524e428d0
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d95cbeef671186421da94a585d6201e524e428d0
Author: Alex Villacís Lasso <a_villacis at palosanto.com>
Date: Sat Apr 26 18:14:13 2008 -0500
richedit: EM_LINELENGTH: honor CR and LF counters.
Add fixup to ME_FindItemAtOffset(), fixes crash by null-pointer access.
Add tests for EM_LINELENGTH.
---
dlls/riched20/editor.c | 19 ++++++++++++++++---
dlls/riched20/tests/editor.c | 36 +++++++++++++++++++++++++++++++++++-
dlls/riched32/tests/editor.c | 34 ++++++++++++++++++++++++++++++++++
3 files changed, 85 insertions(+), 4 deletions(-)
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index da61cd2..01502bf 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -1190,6 +1190,7 @@ ME_DisplayItem *
ME_FindItemAtOffset(ME_TextEditor *editor, ME_DIType nItemType, int nOffset, int *nItemOffset)
{
ME_DisplayItem *item = ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph);
+ int runLength;
while (item && item->member.para.next_para->member.para.nCharOfs <= nOffset)
item = ME_FindItemFwd(item, diParagraph);
@@ -1206,7 +1207,10 @@ ME_FindItemAtOffset(ME_TextEditor *editor, ME_DIType nItemType, int nOffset, int
do {
item = ME_FindItemFwd(item, diRun);
- } while (item && (item->member.run.nCharOfs + ME_StrLen(item->member.run.strText) <= nOffset));
+ runLength = ME_StrLen(item->member.run.strText);
+ if (item->member.run.nFlags & MERF_ENDPARA)
+ runLength = item->member.run.nCR + item->member.run.nLF;
+ } while (item && (item->member.run.nCharOfs + runLength <= nOffset));
if (item) {
nOffset -= item->member.run.nCharOfs;
if (nItemOffset)
@@ -2735,8 +2739,17 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
if (item_end->type == diStartRow)
nNextLineOfs = ME_CharOfsFromRunOfs(editor, ME_FindItemFwd(item_end, diRun), 0);
else
- nNextLineOfs = ME_FindItemFwd(item, diParagraphOrEnd)->member.para.nCharOfs
- - (editor->bEmulateVersion10?2:1);
+ {
+ ME_DisplayItem *endPara;
+
+ nNextLineOfs = ME_FindItemFwd(item, diParagraphOrEnd)->member.para.nCharOfs;
+ endPara = ME_FindItemFwd(item, diParagraphOrEnd);
+ endPara = ME_FindItemBack(endPara, diRun);
+ assert(endPara);
+ assert(endPara->type == diRun);
+ assert(endPara->member.run.nFlags & MERF_ENDPARA);
+ nNextLineOfs -= endPara->member.run.nCR + endPara->member.run.nLF;
+ }
nChars = nNextLineOfs - nThisLineOfs;
TRACE("EM_LINELENGTH(%ld)==%d\n",wParam, nChars);
return nChars;
diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c
index d78c7f6..28b4ce5 100644
--- a/dlls/riched20/tests/editor.c
+++ b/dlls/riched20/tests/editor.c
@@ -261,6 +261,40 @@ static void test_EM_GETLINE(void)
DestroyWindow(hwndRichEdit);
}
+static void test_EM_LINELENGTH(void)
+{
+ HWND hwndRichEdit = new_richedit(NULL);
+ const char * text =
+ "richedit1\r"
+ "richedit1\n"
+ "richedit1\r\n"
+ "richedit1";
+ int offset_test[10][2] = {
+ {0, 9},
+ {5, 9},
+ {10, 9},
+ {15, 9},
+ {20, 9},
+ {25, 9},
+ {30, 9},
+ {35, 9},
+ {40, 0},
+ {45, 0},
+ };
+ int i;
+ LRESULT result;
+
+ SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) text);
+
+ for (i = 0; i < 10; i++) {
+ result = SendMessage(hwndRichEdit, EM_LINELENGTH, offset_test[i][0], 0);
+ ok(result == offset_test[i][1], "Length of line at offset %d is %ld, expected %d\n",
+ offset_test[i][0], result, offset_test[i][1]);
+ }
+
+ DestroyWindow(hwndRichEdit);
+}
+
static int get_scroll_pos_y(HWND hwnd)
{
POINT p = {-1, -1};
@@ -2972,7 +3006,6 @@ static void test_eventMask(void)
}
-
START_TEST( editor )
{
MSG msg;
@@ -2989,6 +3022,7 @@ START_TEST( editor )
test_EM_SCROLLCARET();
test_EM_SCROLL();
test_WM_SETTEXT();
+ test_EM_LINELENGTH();
test_EM_SETCHARFORMAT();
test_EM_SETTEXTMODE();
test_TM_PLAINTEXT();
diff --git a/dlls/riched32/tests/editor.c b/dlls/riched32/tests/editor.c
index 106cd65..6fe027b 100644
--- a/dlls/riched32/tests/editor.c
+++ b/dlls/riched32/tests/editor.c
@@ -430,6 +430,39 @@ static void test_EM_GETLINE(void)
DestroyWindow(hwndRichEdit);
}
+static void test_EM_LINELENGTH(void)
+{
+ HWND hwndRichEdit = new_richedit(NULL);
+ const char * text =
+ "richedit1\r"
+ "richedit1\n"
+ "richedit1\r\n"
+ "richedit1\r\r\r\r\r\n";
+ int offset_test[10][2] = {
+ {0, 9},
+ {5, 9},
+ {10, 9},
+ {15, 9},
+ {20, 9},
+ {25, 9},
+ {30, 9},
+ {35, 9},
+ {40, 9}, /* <----- in the middle of the \r run, but run not counted */
+ {45, 0},
+ };
+ int i;
+ LRESULT result;
+
+ SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) text);
+
+ for (i = 0; i < 10; i++) {
+ result = SendMessage(hwndRichEdit, EM_LINELENGTH, offset_test[i][0], 0);
+ ok(result == offset_test[i][1], "Length of line at offset %d is %ld, expected %d\n",
+ offset_test[i][0], result, offset_test[i][1]);
+ }
+
+ DestroyWindow(hwndRichEdit);
+}
START_TEST( editor )
{
@@ -446,6 +479,7 @@ START_TEST( editor )
test_EM_STREAMIN();
test_EM_STREAMOUT();
test_EM_GETLINE();
+ test_EM_LINELENGTH();
/* Set the environment variable WINETEST_RICHED32 to keep windows
* responsive and open for 30 seconds. This is useful for debugging.
More information about the wine-cvs
mailing list