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:
parent
3968a67eb9
commit
d95cbeef67
|
@ -1190,6 +1190,7 @@ ME_DisplayItem *
|
||||||
ME_FindItemAtOffset(ME_TextEditor *editor, ME_DIType nItemType, int nOffset, int *nItemOffset)
|
ME_FindItemAtOffset(ME_TextEditor *editor, ME_DIType nItemType, int nOffset, int *nItemOffset)
|
||||||
{
|
{
|
||||||
ME_DisplayItem *item = ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph);
|
ME_DisplayItem *item = ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph);
|
||||||
|
int runLength;
|
||||||
|
|
||||||
while (item && item->member.para.next_para->member.para.nCharOfs <= nOffset)
|
while (item && item->member.para.next_para->member.para.nCharOfs <= nOffset)
|
||||||
item = ME_FindItemFwd(item, diParagraph);
|
item = ME_FindItemFwd(item, diParagraph);
|
||||||
|
@ -1206,7 +1207,10 @@ ME_FindItemAtOffset(ME_TextEditor *editor, ME_DIType nItemType, int nOffset, int
|
||||||
|
|
||||||
do {
|
do {
|
||||||
item = ME_FindItemFwd(item, diRun);
|
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) {
|
if (item) {
|
||||||
nOffset -= item->member.run.nCharOfs;
|
nOffset -= item->member.run.nCharOfs;
|
||||||
if (nItemOffset)
|
if (nItemOffset)
|
||||||
|
@ -2735,8 +2739,17 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
||||||
if (item_end->type == diStartRow)
|
if (item_end->type == diStartRow)
|
||||||
nNextLineOfs = ME_CharOfsFromRunOfs(editor, ME_FindItemFwd(item_end, diRun), 0);
|
nNextLineOfs = ME_CharOfsFromRunOfs(editor, ME_FindItemFwd(item_end, diRun), 0);
|
||||||
else
|
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;
|
nChars = nNextLineOfs - nThisLineOfs;
|
||||||
TRACE("EM_LINELENGTH(%ld)==%d\n",wParam, nChars);
|
TRACE("EM_LINELENGTH(%ld)==%d\n",wParam, nChars);
|
||||||
return nChars;
|
return nChars;
|
||||||
|
|
|
@ -261,6 +261,40 @@ static void test_EM_GETLINE(void)
|
||||||
DestroyWindow(hwndRichEdit);
|
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)
|
static int get_scroll_pos_y(HWND hwnd)
|
||||||
{
|
{
|
||||||
POINT p = {-1, -1};
|
POINT p = {-1, -1};
|
||||||
|
@ -2972,7 +3006,6 @@ static void test_eventMask(void)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
START_TEST( editor )
|
START_TEST( editor )
|
||||||
{
|
{
|
||||||
MSG msg;
|
MSG msg;
|
||||||
|
@ -2989,6 +3022,7 @@ START_TEST( editor )
|
||||||
test_EM_SCROLLCARET();
|
test_EM_SCROLLCARET();
|
||||||
test_EM_SCROLL();
|
test_EM_SCROLL();
|
||||||
test_WM_SETTEXT();
|
test_WM_SETTEXT();
|
||||||
|
test_EM_LINELENGTH();
|
||||||
test_EM_SETCHARFORMAT();
|
test_EM_SETCHARFORMAT();
|
||||||
test_EM_SETTEXTMODE();
|
test_EM_SETTEXTMODE();
|
||||||
test_TM_PLAINTEXT();
|
test_TM_PLAINTEXT();
|
||||||
|
|
|
@ -430,6 +430,39 @@ static void test_EM_GETLINE(void)
|
||||||
DestroyWindow(hwndRichEdit);
|
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 )
|
START_TEST( editor )
|
||||||
{
|
{
|
||||||
|
@ -446,6 +479,7 @@ START_TEST( editor )
|
||||||
test_EM_STREAMIN();
|
test_EM_STREAMIN();
|
||||||
test_EM_STREAMOUT();
|
test_EM_STREAMOUT();
|
||||||
test_EM_GETLINE();
|
test_EM_GETLINE();
|
||||||
|
test_EM_LINELENGTH();
|
||||||
|
|
||||||
/* Set the environment variable WINETEST_RICHED32 to keep windows
|
/* Set the environment variable WINETEST_RICHED32 to keep windows
|
||||||
* responsive and open for 30 seconds. This is useful for debugging.
|
* responsive and open for 30 seconds. This is useful for debugging.
|
||||||
|
|
Loading…
Reference in New Issue