richedit: EM_LINELENGTH: honor CR and LF counters.

Add fixup to ME_FindItemAtOffset(), fixes crash by null-pointer access.
Add tests for EM_LINELENGTH.
This commit is contained in:
Alex Villacís Lasso 2008-04-26 18:14:13 -05:00 committed by Alexandre Julliard
parent 3968a67eb9
commit d95cbeef67
3 changed files with 85 additions and 4 deletions

View File

@ -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;

View File

@ -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();

View File

@ -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.