SVN commit 720983 by amantia: This should finally fix all the cases when Quanta crashes due to double free in the node tree. It's more a workaround, but that's what I have now... M +1 -0 ChangeLog M +10 -10 components/tableeditor/tableeditor.cpp M +12 -2 parsers/node.cpp M +8 -0 parsers/node.h M +5 -5 parsers/parser.cpp M +2 -2 parsers/saparser.cpp M +8 -8 parts/kafka/kafkacommon.cpp M +3 -3 parts/kafka/undoredo.cpp M +2 -2 quanta.kdevelop M +4 -4 src/document.cpp M +2 -2 src/quantaview.cpp --- branches/KDE/3.5/kdewebdev/quanta/ChangeLog #720982:720983 @@ -6,6 +6,7 @@ - fix add to project when saving a new file into a symlinked directory [#148529] - do not lose CSS selectors after editing inside the dialog if they are repeated [#145413] + - avoid crashes in various (random) cases Version 3.5.7 (Release date: xx-xx-2006; Started 06-02-2006) --- branches/KDE/3.5/kdewebdev/quanta/components/tableeditor/tableeditor.cpp #720982:720983 @@ -930,14 +930,14 @@ updatedMainNodes.append(mainTableNode); } } - delete (*it3).node; + Node::deleteNode((*it3).node); (*it3).node = 0L; newNum--; } m_tableTags->erase(it2); m_dataTable->removeRow(m_row); QValueList::Iterator it = m_tableRows->at(m_row); - delete (*it).node; + Node::deleteNode((*it).node); newNum--; m_tableRows->erase(it); m_rowSpin->setValue(m_dataTable->numRows()); @@ -981,7 +981,7 @@ updatedMainNodes.append(mainTableNode); } } - delete (*it2).node; + Node::deleteNode((*it2).node); newNum--; (*it).erase(it2); } @@ -1021,7 +1021,7 @@ void TableEditor::deleteList( QValueList *table ) { for (QValueList::Iterator it = table->begin(); it != table->end(); ++it) { - delete (*it).node; + Node::deleteNode((*it).node); newNum--; } delete table; @@ -1033,7 +1033,7 @@ { for (QValueList >::Iterator it = matrix->begin(); it != matrix->end(); ++it) { for (QValueList::Iterator it2 = (*it).begin(); it2 != (*it).end(); ++it2) { - delete (*it2).node; + Node::deleteNode((*it2).node); newNum--; } } @@ -1063,7 +1063,7 @@ setCellText(m_dataTable, tRow + i, lCol + j, i18n("Merged with (%1, %2).").arg(tRow + 1).arg(lCol + 1)); m_dataTable->item(tRow + i, lCol + j)->setEnabled(false); TableNode *tableNode = &((*m_tableTags)[tRow + i][lCol + j]); - delete tableNode->node; + Node::deleteNode(tableNode->node); tableNode->node = new Node(0L); newNum++; tableNode->node->tag = new Tag(*(mainTableNode->node->tag)); @@ -1107,7 +1107,7 @@ tableNode.mergedRow == (*it2).mergedRow && tableNode.mergedCol == (*it2).mergedCol) { - delete (*it2).node; + Node::deleteNode((*it2).node); newNum--; it2 = (*it).erase(it2); newTableNode.merged = false; @@ -1142,7 +1142,7 @@ QValueList::Iterator iter2 = (*iter1).at(tableNode.mergedCol); iter2 = (*iter1).erase(iter2); (*iter1).insert(iter2, newTableNode); - delete tmpNode.node; + Node::deleteNode(tmpNode.node); newNum--; } } @@ -1218,7 +1218,7 @@ setCellText(m_dataTable, table.row, table.col, cellData); } //cleanup on success - delete baseNode; + Node::deleteNode(baseNode); baseNode = savedBaseNode; delete localParser; delete w; @@ -1231,7 +1231,7 @@ m_dataTable->item(table.row, table.col)->setPixmap(QPixmap()); m_dataTable->updateCell(table.row, table.col); if (tempDocCreated) { - delete baseNode; + Node::deleteNode(baseNode); baseNode = savedBaseNode; delete localParser; delete w; --- branches/KDE/3.5/kdewebdev/quanta/parsers/node.cpp #720982:720983 @@ -56,6 +56,16 @@ } } +bool Node::deleteNode(Node *node) +{ + if (nodes.contains(node) == 0) + { + //kdDebug(24000) << "Trying to delete a node with address " << node << " that was not allocated!" << endl; + return false; + } + delete node; + return true; +} Node::~Node() { @@ -82,9 +92,9 @@ parent->child = 0L; if (removeAll) { - delete child; + deleteNode(child); child = 0L; - delete next; + deleteNode(next); next = 0L; } else { --- branches/KDE/3.5/kdewebdev/quanta/parsers/node.h #720982:720983 @@ -63,6 +63,14 @@ public: Node( Node *parent ); ~Node(); + + /** + * Deletes the node. Use this instead of delete node; as it checkes if there + * node was really allocated or not and avoid nasty crashes. + * @return true - if node existed and is deleted + * false - if the node did not exist + */ + static bool deleteNode(Node *node); /** * Copy everything from node except prev, next, child, parent, listItem, group, groupTag, which are set to Null --- branches/KDE/3.5/kdewebdev/quanta/parsers/parser.cpp #720982:720983 @@ -524,12 +524,12 @@ kdDebug(24000) << "Node objects before delete = " << NN << " ; list count = " << nodes.count() << endl; //kdDebug(24000) << "baseNode before delete = " << baseNode << endl; //ParserCommon::coutTree(m_node, 2); - delete baseNode; + Node::deleteNode(baseNode); baseNode = 0L; kdDebug(24000) << "Node objects after delete = " << NN << " ; list count = " << nodes.count() << endl; QValueList nList = nodes; /* for (QValueList::ConstIterator it = nList.constBegin(); it != nList.constEnd(); ++it) - delete (*it); + Node::deleteNode(*it); kdDebug(24000) << "Node objects after cleanup = " << NN << " ; list count = " << nodes.count() << endl; */ } m_node = 0L; @@ -1056,7 +1056,7 @@ if (lastNode->parent && lastNode->parent->child == lastNode) lastNode->parent->child = 0L; } - delete lastNode; + Node::deleteNode(lastNode); nodeNum--; lastNode = 0L; logReparse(modifs, w); @@ -1357,7 +1357,7 @@ { GroupElement *groupElement = it.data()[i]; groupElement->node->tag->write()->userTagList.remove(groupElement->node->tag->name.lower()); - delete it.data()[i]->node; + Node::deleteNode(it.data()[i]->node); delete it.data()[i]; } } @@ -1611,7 +1611,7 @@ uint listCount = it.data().count(); for (uint i = 0 ; i < listCount; i++) { - delete it.data()[i]->node; + Node::deleteNode(it.data()[i]->node); delete it.data()[i]; } } --- branches/KDE/3.5/kdewebdev/quanta/parsers/saparser.cpp #720982:720983 @@ -895,7 +895,7 @@ m_currentNode->tag->type != Tag::Text && m_currentNode->tag->type != Tag::Empty) { - delete m_currentNode->child; + Node::deleteNode(m_currentNode->child); m_currentNode->child = 0L; AreaStruct area(m_currentNode->tag->area()); s_next = 0L; @@ -913,7 +913,7 @@ Node *secondNext = m_currentNode->next->next; if (secondNext) secondNext->prev = m_currentNode; - delete m_currentNode->next; + Node::deleteNode(m_currentNode->next); m_currentNode->next = secondNext; m_useNext = true; } --- branches/KDE/3.5/kdewebdev/quanta/parts/kafka/kafkacommon.cpp #720982:720983 @@ -1513,7 +1513,7 @@ if(!startNode || !endNode || !newNode || !doc) { - delete newNode; + Node::deleteNode(newNode); return false; } @@ -1523,8 +1523,8 @@ newNodeQTag = QuantaCommon::tagFromDTD(newNode); if(!newNodeQTag || !lastNewNodeQTag) { - delete newNode; - return false; + Node::deleteNode(newNode); + return false; } //Then search for the common parent of startNode and endNode (commonParent) @@ -1608,8 +1608,8 @@ /**if(!lastValidEndParent || !lastValidStartParent) { - delete newNode; - return false; + Node::deleteNode(newNode); + return false; }*/ //OK now, we are sure the node can be inserted. Start the work by splitting @@ -1749,8 +1749,8 @@ } else { - delete newNode; - return false; + Node::deleteNode(newNode); + return false; } } else @@ -2108,7 +2108,7 @@ //The newNode was a template, let's delete it now. if(level == 0) - delete newNode; + Node::deleteNode(newNode); return true; } --- branches/KDE/3.5/kdewebdev/quanta/parts/kafka/undoredo.cpp #720982:720983 @@ -64,7 +64,7 @@ m_node->prev = 0L; if(m_type == NodeRemoved) m_node->child = 0L; - delete m_node; + Node::deleteNode(m_node); } if(m_tag) delete m_tag; @@ -77,9 +77,9 @@ { //FIXME: Andras: I don't have the slightest idea what this is supposed to do and what the //below comment means, but without a real delete we are seriously leaking memory - delete m_node; + Node::deleteNode(m_node); m_node = 0L; - delete node; + Node::deleteNode(node); return; } else --- branches/KDE/3.5/kdewebdev/quanta/quanta.kdevelop #720982:720983 @@ -259,10 +259,10 @@ - + Quanta speicfic header - + A new empty C++ file. --- branches/KDE/3.5/kdewebdev/quanta/src/document.cpp #720982:720983 @@ -2430,12 +2430,12 @@ if ( (bl != bl2 || bc !=bc2) && previousNode) { previousNode->tag->beginPos(bl2, bc2); - delete currentNode; + Node::deleteNode(currentNode); currentNode = previousNode; previousNode = 0L; } else { - delete previousNode; + Node::deleteNode(previousNode); previousNode = 0L; } if (bl == bl2 && bc == bc2 && @@ -2502,8 +2502,8 @@ } } } - delete currentNode; - delete previousNode; + Node::deleteNode(currentNode); + Node::deleteNode(previousNode); } quantaApp->slotNewLineColumn(); --- branches/KDE/3.5/kdewebdev/quanta/src/quantaview.cpp #720982:720983 @@ -146,12 +146,12 @@ { parser->setSAParserEnabled(false); kdDebug(24000) << "Node objects before delete = " << NN << " ; list count = " << nodes.count() << endl; - delete baseNode; + Node::deleteNode(baseNode); baseNode = 0L; kdDebug(24000) << "Node objects after delete = " << NN << " ; list count = " << nodes.count() << endl; QValueList nList = nodes; /* for (QValueList::ConstIterator it = nList.constBegin(); it != nList.constEnd(); ++it) - delete (*it); + Node::deleteNode(*it); kdDebug(24000) << "Node objects after cleanup = " << NN << " ; list count = " << nodes.count() << endl;*/ } if (m_document)