From 8e0159f197444b79869f00eacd2ca68d72575fbf Mon Sep 17 00:00:00 2001 From: Vadim Kurland Date: Thu, 27 Jan 2011 19:23:53 -0800 Subject: [PATCH] see #1996 --- VERSION | 2 +- VERSION.h | 2 +- doc/ChangeLog | 12 +++++++ packaging/fwbuilder-static-qt.spec | 2 +- packaging/fwbuilder.control | 2 +- packaging/fwbuilder.spec | 2 +- src/libgui/FWCmdBasic.cpp | 6 ++-- src/libgui/ProjectPanel.cpp | 50 +++++++++++++++++++++++++----- src/libgui/ProjectPanel_events.cpp | 4 ++- 9 files changed, 66 insertions(+), 16 deletions(-) diff --git a/VERSION b/VERSION index 08a787aa8..04df09d99 100644 --- a/VERSION +++ b/VERSION @@ -7,7 +7,7 @@ FWB_MICRO_VERSION=0 # build number is like "nano" version number. I am incrementing build # number during development cycle # -BUILD_NUM="3450" +BUILD_NUM="3451" VERSION="$FWB_MAJOR_VERSION.$FWB_MINOR_VERSION.$FWB_MICRO_VERSION.$BUILD_NUM" diff --git a/VERSION.h b/VERSION.h index 7ca09158c..f286a6c62 100644 --- a/VERSION.h +++ b/VERSION.h @@ -1,2 +1,2 @@ -#define VERSION "4.2.0.3450" +#define VERSION "4.2.0.3451" #define GENERATION "4.2" diff --git a/doc/ChangeLog b/doc/ChangeLog index a86642622..ea48eea6c 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,5 +1,17 @@ 2011-01-27 vadim + * ProjectPanel.cpp (registerModifiedObject): see #1996 "Crash when + finding and replacing a large number of objects". When "find and + replace" function was used to replace large number of objects in a + rule set, it generated stream of calls to + updateLastModifiedTimestampForAllFirewalls() which caused + corresponding stream of events to update various parts of the GUI, + both in the tree and rule set views. This caused weird corruption + and crash on Windows. Trying to resolve the issue by optimizing + the part that updated "last modified" timestamp on the firewall + since all parts of the rule set updated in one call to "find and + replace" function belong to the same firewall. + * IOSImporterRun.cpp (run): see #1931 "Update failed import behavior". Added meaningful error messages for when policy importer fails to create firewall object or does not create diff --git a/packaging/fwbuilder-static-qt.spec b/packaging/fwbuilder-static-qt.spec index 169074ce3..2b7f209a4 100644 --- a/packaging/fwbuilder-static-qt.spec +++ b/packaging/fwbuilder-static-qt.spec @@ -3,7 +3,7 @@ %define name fwbuilder -%define version 4.2.0.3450 +%define version 4.2.0.3451 %define release 1 %if "%_vendor" == "MandrakeSoft" diff --git a/packaging/fwbuilder.control b/packaging/fwbuilder.control index 89e35d5cb..ab31ad341 100644 --- a/packaging/fwbuilder.control +++ b/packaging/fwbuilder.control @@ -4,6 +4,6 @@ Replaces: fwbuilder (<=4.1.1-1), fwbuilder-common, fwbuilder-bsd, fwbuilder-linu Priority: extra Section: checkinstall Maintainer: vadim@fwbuilder.org -Version: 4.2.0.3450-1 +Version: 4.2.0.3451-1 Depends: libqt4-gui (>= 4.3.0), libxml2, libxslt1.1, libsnmp | libsnmp15 Description: Firewall Builder GUI and policy compilers diff --git a/packaging/fwbuilder.spec b/packaging/fwbuilder.spec index ead7d7114..fb1706a85 100644 --- a/packaging/fwbuilder.spec +++ b/packaging/fwbuilder.spec @@ -1,6 +1,6 @@ %define name fwbuilder -%define version 4.2.0.3450 +%define version 4.2.0.3451 %define release 1 %if "%_vendor" == "MandrakeSoft" diff --git a/src/libgui/FWCmdBasic.cpp b/src/libgui/FWCmdBasic.cpp index 55169f34f..eadf576b6 100644 --- a/src/libgui/FWCmdBasic.cpp +++ b/src/libgui/FWCmdBasic.cpp @@ -49,7 +49,8 @@ bool FWCmdBasic::mergeWith(const QUndoCommand *other) { if (fwbdebug) { - qDebug() << "FWCmdBasic::mergeWith(const QUndoCommand *other) other=" << other; + qDebug() << "FWCmdBasic::mergeWith(const QUndoCommand *other) other=" + << other; qDebug() << "cmd:" << other->text(); } const FWCmdTerm* term = dynamic_cast(other); @@ -60,7 +61,8 @@ bool FWCmdMacro::mergeWith(const QUndoCommand *other) { if (fwbdebug) { - qDebug() << "FWCmdMacro::mergeWith(const QUndoCommand *other) other=" << other; + qDebug() << "FWCmdMacro::mergeWith(const QUndoCommand *other) other=" + << other; qDebug() << "cmd:" << other->text(); } const FWCmdTerm* term = dynamic_cast (other); diff --git a/src/libgui/ProjectPanel.cpp b/src/libgui/ProjectPanel.cpp index 3b83d386f..bf9a3bb23 100644 --- a/src/libgui/ProjectPanel.cpp +++ b/src/libgui/ProjectPanel.cpp @@ -1107,7 +1107,9 @@ void ProjectPanel::registerObjectToUpdateInTree(FWObject *o, bool update_subtree qDebug() << "ProjectPanel::registerObjectToUpdateInTree()" << "o=" << o->getName().c_str() << "update_subtree=" << update_subtree - << "updateObjectsInTreePool.size()=" << updateObjectsInTreePool.size(); + << "updateObjectsInTreePool.size()=" + << updateObjectsInTreePool.size(); + if (updateObjectsInTreePool.find(o->getId()) == updateObjectsInTreePool.end()) { updateObjectsInTreePool[o->getId()] = update_subtree; @@ -1119,7 +1121,8 @@ void ProjectPanel::updateObjectInTree() { if (fwbdebug) qDebug() << "ProjectPanel::updateObjectInTree()" - << "updateObjectsInTreePool.size()=" << updateObjectsInTreePool.size(); + << "updateObjectsInTreePool.size()=" + << updateObjectsInTreePool.size(); while (updateObjectsInTreePool.size() > 0) { @@ -1135,12 +1138,42 @@ void ProjectPanel::registerModifiedObject(FWObject *o) { if (fwbdebug) qDebug() << "ProjectPanel::registerModifiedObject " - << "lastModifiedTimestampChangePool.size()=" << lastModifiedTimestampChangePool.size() - << "o=" << o->getName().c_str(); - if (lastModifiedTimestampChangePool.find(o->getId()) == lastModifiedTimestampChangePool.end()) + << "lastModifiedTimestampChangePool.size()=" + << lastModifiedTimestampChangePool.size() + << "o=" << o->getName().c_str() + << "(" << o->getTypeName().c_str() << ")" + << "id=" << o->getId(); + + FWObject *modified_object = o; + + /* + * a bit of optimization: the purpose of registering modified + * object here is to update "last modified" timestamp in the + * firewall object it belongs to. One of the frequent cases is + * when @o is rule element because user made some change to + * it. Massive find and replace operations can cause waves of + * registrations of rule elements, all of which belong to the + * same rule set. If I register rule set instead, there will be + * just one object to register. + */ + + if (RuleElement::cast(o)) { - lastModifiedTimestampChangePool.insert(o->getId()); - QTimer::singleShot(0, this, SLOT(updateLastModifiedTimestampForAllFirewalls())); + while (RuleSet::cast(modified_object) == NULL) + modified_object = modified_object->getParent(); + } + + if (lastModifiedTimestampChangePool.find(modified_object->getId()) == + lastModifiedTimestampChangePool.end()) + { + if (fwbdebug) + qDebug() << "ProjectPanel::registerModifiedObject " + << "Add object" << modified_object->getName().c_str() + << "id=" << modified_object->getId(); + + lastModifiedTimestampChangePool.insert(modified_object->getId()); + QTimer::singleShot( + 0, this, SLOT(updateLastModifiedTimestampForAllFirewalls())); } } @@ -1153,7 +1186,8 @@ void ProjectPanel::updateLastModifiedTimestampForAllFirewalls() if (lastModifiedTimestampChangePool.size() == 0) return; - mw->showStatusBarMessage(tr("Searching for firewalls affected by the change...")); + mw->showStatusBarMessage( + tr("Searching for firewalls affected by the change...")); //QApplication::processEvents(QEventLoop::ExcludeUserInputEvents,100); diff --git a/src/libgui/ProjectPanel_events.cpp b/src/libgui/ProjectPanel_events.cpp index 8db8e829c..72566a5a9 100644 --- a/src/libgui/ProjectPanel_events.cpp +++ b/src/libgui/ProjectPanel_events.cpp @@ -73,7 +73,9 @@ bool ProjectPanel::event(QEvent *event) << "event:" << ev->getEventName() << "object:" - << ((obj!=NULL) ? QString::fromUtf8(obj->getName().c_str()) : ""); + << ((obj!=NULL) ? QString::fromUtf8(obj->getName().c_str()) : "") + << "(" << ((obj!=NULL) ? obj->getTypeName().c_str() : "") << ")" + << "id=" << ((obj!=NULL) ? obj->getId() : -1); if (event_code == UPDATE_GUI_STATE_EVENT && mdiWindow != NULL) {