GNOME Bugzilla – Bug 235557
change table row/column hang the editor
Last modified: 2003-02-11 16:15:38 UTC
Please fill in this template when reporting a bug, unless you know what you are doing. Description of Problem: Steps to reproduce the problem: 1. in evolution, new a message 2. insert a table of default 3*3 dimension. 3. click the *outmost bound* of the table. Note, select the cell in the table cannnot reproduce the bug. 4. right click the menu and select 'Table', and in the 'table' tab of the popup dialog, change the size of the table. change the rows or column number. click OK now. Actual Results: System crash Expected Results: do not crash How often does this happen? Always Additional Information:
Created attachment 41858 [details] [review] patch to show where the problem is
It is not segment fault, actually, the evolution hang there, and top command show more than 90% of cpu usage. Problems are in html_engine_table_set_cols() and html_engine_table_set_rows(). In this function, it just call html_engine_insert_table_row/column() in a while loop to insert row(column). See the code below, html_engine_table_set_cols() { ... ... if (table->totalCols < cols) { html_engine_table_goto_col (e, table->totalCols - 1); while (table->totalCols < cols) if (!html_engine_insert_table_column (e, TRUE)) break; } else { html_engine_table_goto_col (e, table->totalCols - 1); while (table->totalCols > cols) if (!html_engine_delete_table_column (e)) break; } ... ... } The problem is that html_engine_insert_table_row() may failed. In this case, because I select the outmost table bound, html_engine_insert_table_column() will failed because when it get 2th parent, it is will not be TABLE_CELL. see below: html_engine_insert_table_column (HTMLEngine *e, gboolean after) { ... ... cell = html_object_nth_parent (e->cursor->object, 2); if (cell && HTML_IS_TABLE_CELL (cell)) insert_table_column()... } thus the function returned without doing any thing. but the while loop just loop. Thus the hang. The attached patch is not intend to be the final patch. It just prevent evolution from running into dead loop. After user change row/column and click OK button, nothing changed. The patch may not good because user maybe confused when the change not happen. A better fix maybe just disable the function of change row/col in this case. I will try to work out a patch with disable change of col size.
After digging into code, I found this acutally is caused by we do not differentiate between what you select is table or a table cell. Some table edit code just assume what selected is table cell, and some other code just return itself or its parent whichever is table. The example of first case like html_engine_insert_table_row(), and the second like html_engine_get_table(). Besides this logged bugged, the problems mentioned above also introduce many other issues. If you create a table with sub-table, the table and subtable are of different size. Now select the sub-table, and right click and edit the properties of the table. The edit dialog has two tab with the name 'table'. Actually one of them is for the sub-table itself, and the other is for table contain the subtable. But you will find the dimension of the two table is actually the same. I will keep work on it.
It's probably not worth fixing in 1.4. In CVS version it's already fixed, so I will probably just commit small patch to avoid looping.
I have checked both CVS 1.1.7 and trunk. Both html_engine_get_table() and html_engine_get_table_cell() are still being used. As I have mentioned above, they just get a table, either itself or its parent->parent. And then use it blindly. This will cause problem when table is a subtable of another table. So at least this problem is not yet fixed even in trunk. I have write a patch for the bug, though still need work. Just a demo. See attachment.
Created attachment 41879 [details] [review] patch for demo resolve the problems
The patch attached works by: 1. First we need to differentiate whether user selected is the table itself or the table->parent->parent.This is done in the process of generate popup menu and dialog. See prepare_properties_and_menu(). 2. Add a flag /self/ into struct GtkHTMLEditTableProperties. And use the flag to record result of 1. Add a table_properties_2() to generate edit-table dialog data just for the case that user selected is table itself. Because original code actually work for the other case (table->parent->parent is selected). 3. Add a function that return either itself as table or parent->parent as table. With explicit specified. 4. The last work focus on html_engine_table_set_cols() and html_engine_table_set_row(). We modified them so that in table_apply_cb() callback, we can pass it the flag to indicate if we select is table itself. And the process the row, column modification work correspondingly.
*** bug 234594 has been marked as a duplicate of this bug. ***
There is another crash caused by the bad design, follow steps as below 1. Select the outmost bound of the table. 2. Insert a table when compose a mail, delete one column. 3. Ctrl+Z to undo. the editor crash.
Created attachment 41882 [details] [review] better patch
Oh, you are right. html_engine_get_table should never return e->cursor->object. I will attach shorter fix to reply to your e-h mail. The delete column/UNDO problem is different and is indeed fixed in CVS trunk. I am not sure if it's worth to backport to 1.2.x.
OK, it just another solution with lower risk.
This is fixed, close it.
Closing as per last comment.