nCharOfs is the key for paragraphs added to the marked tree If it is updated, re-add the entry to update its position
From: Daniel Lehman dlehman25@gmail.com
nCharOfs is the key for paragraphs added to the marked tree If it is updated, re-add the entry to update its position --- dlls/riched20/caret.c | 2 +- dlls/riched20/editor.h | 2 +- dlls/riched20/para.c | 4 ++-- dlls/riched20/run.c | 10 ++++++++-- dlls/riched20/tests/editor.c | 11 +++++++++++ 5 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/dlls/riched20/caret.c b/dlls/riched20/caret.c index f89770ccc75..eed4bbf26bc 100644 --- a/dlls/riched20/caret.c +++ b/dlls/riched20/caret.c @@ -416,7 +416,7 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start, /* c = updated data now */
if (c.run == cursor.run) c.run->nCharOfs -= shift; - editor_propagate_char_ofs( NULL, c.run, shift ); + editor_propagate_char_ofs( editor, NULL, c.run, shift );
if (!cursor.run->len) { diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h index 072d0f62782..d3e4f49da7b 100644 --- a/dlls/riched20/editor.h +++ b/dlls/riched20/editor.h @@ -129,7 +129,7 @@ static inline ME_DisplayItem *row_get_di( ME_Row *row ) void cursor_from_char_ofs( ME_TextEditor *editor, int char_ofs, ME_Cursor *cursor ) DECLSPEC_HIDDEN; BOOL cursor_next_run( ME_Cursor *cursor, BOOL all_para ) DECLSPEC_HIDDEN; BOOL cursor_prev_run( ME_Cursor *cursor, BOOL all_para ) DECLSPEC_HIDDEN; -void editor_propagate_char_ofs( ME_Paragraph *para, ME_Run *run, int shift ) DECLSPEC_HIDDEN; +void editor_propagate_char_ofs( ME_TextEditor *editor, ME_Paragraph *para, ME_Run *run, int shift ) DECLSPEC_HIDDEN; int run_char_ofs( ME_Run *run, int ofs ) DECLSPEC_HIDDEN; ME_Run *run_create( ME_Style *s, int nFlags ) DECLSPEC_HIDDEN; ME_Run *run_insert( ME_TextEditor *editor, ME_Cursor *cursor, diff --git a/dlls/riched20/para.c b/dlls/riched20/para.c index 166b1fcd45b..357d6797c8c 100644 --- a/dlls/riched20/para.c +++ b/dlls/riched20/para.c @@ -671,7 +671,7 @@ ME_Paragraph *para_split( ME_TextEditor *editor, ME_Run *run, ME_Style *style, para_mark_rewrap( editor, &new_para->prev_para->member.para );
/* we've added the end run, so we need to modify nCharOfs in the next paragraphs */ - editor_propagate_char_ofs( next_para, NULL, eol_len ); + editor_propagate_char_ofs( editor, next_para, NULL, eol_len ); editor->nParagraphs++;
return new_para; @@ -774,7 +774,7 @@ ME_Paragraph *para_join( ME_TextEditor *editor, ME_Paragraph *para, BOOL use_fir ME_Remove( para_get_di(next) ); para_destroy( editor, next );
- editor_propagate_char_ofs( para_next( para ), NULL, -end_len ); + editor_propagate_char_ofs( editor, para_next( para ), NULL, -end_len );
ME_CheckCharOffsets(editor);
diff --git a/dlls/riched20/run.c b/dlls/riched20/run.c index f01f61c181a..2ebc4548868 100644 --- a/dlls/riched20/run.c +++ b/dlls/riched20/run.c @@ -144,7 +144,7 @@ BOOL ME_CanJoinRuns(const ME_Run *run1, const ME_Run *run2) * the document) of the part of the text starting from given place. * Call with only one of para or run non-NULL. */ -void editor_propagate_char_ofs( ME_Paragraph *para, ME_Run *run, int shift ) +void editor_propagate_char_ofs( ME_TextEditor *editor, ME_Paragraph *para, ME_Run *run, int shift ) { assert( !para ^ !run );
@@ -161,6 +161,12 @@ void editor_propagate_char_ofs( ME_Paragraph *para, ME_Run *run, int shift ) do { para->nCharOfs += shift; + /* update position in marked tree, if added */ + if (para->nFlags & MEPF_REWRAP) + { + para_mark_remove( editor, para ); + para_mark_add( editor, para ); + } para = para_next( para ); } while (para); } @@ -400,7 +406,7 @@ ME_Run *run_insert( ME_TextEditor *editor, ME_Cursor *cursor, ME_Style *style, ME_InsertString( run->para->text, run->nCharOfs, str, len ); ME_InsertBefore( run_get_di( insert_before ), run_get_di( run ) ); TRACE("Shift length:%d\n", len); - editor_propagate_char_ofs( NULL, insert_before, len ); + editor_propagate_char_ofs( editor, NULL, insert_before, len ); para_mark_rewrap( editor, insert_before->para );
/* Move any cursors that were at the end of the previous run to the end of the inserted run */ diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c index 4f4d637b687..9682a4ad99f 100644 --- a/dlls/riched20/tests/editor.c +++ b/dlls/riched20/tests/editor.c @@ -8889,6 +8889,8 @@ static void test_rtf(void) 0x201d,0x200e,0x200f,0x200d,0x200c}; const char *pard = "{\rtf1 ABC\rtlpar\par DEF\par HIJ\pard\par}"; const char *highlight = "{\rtf1{\colortbl;\red0\green0\blue0;\red128\green128\blue128;\red192\green192\blue192;}\cf2\highlight3 foo\par}"; + const char *crash = "{\rtf2 {\par \pard \trowd \cellx6000 \intbl \cell \row \par \pard \li300 \bullet packages... \par }"; + const char *crash2 = "{\rtf1 \trowd row1 \intbl \cell \row \par \trowd row2 \intbl \cell \row}";
HWND edit = new_richeditW( NULL ); EDITSTREAM es; @@ -8940,6 +8942,15 @@ static void test_rtf(void) ok( cf.crTextColor == RGB(128,128,128), "got %08lx\n", cf.crTextColor ); ok( cf.crBackColor == RGB(192,192,192), "got %08lx\n", cf.crBackColor );
+ /* Test cases that crash */ + es.dwCookie = (DWORD_PTR)&crash; + es.dwError = 0; + SendMessageA( edit, EM_STREAMIN, SF_RTF, (LPARAM)&es ); + + es.dwCookie = (DWORD_PTR)&crash2; + es.dwError = 0; + SendMessageA( edit, EM_STREAMIN, SF_RTF, (LPARAM)&es ); + DestroyWindow( edit ); }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=133578
Your paranoid android.
=== debian11 (32 bit ja:JP report) ===
riched20: editor.c:5746: Test failed: Failed to paste clipboard content
Huw Davies (@huw) commented about dlls/riched20/run.c:
do { para->nCharOfs += shift;
/* update position in marked tree, if added */
if (para->nFlags & MEPF_REWRAP)
{
para_mark_remove( editor, para );
para_mark_add( editor, para );
}
I guess we'd also want `para_mark_remove()` to use `wine_rb_remove()` rather than `wine_rb_remove_key()`.