diff --git a/doc/ChangeLog b/doc/ChangeLog index bc20bf170..a7fdb6f39 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,10 @@ +2011-07-13 theron + * Fixed #2505: make sure that objects that we show are members of + a dynamic group are actually objects. Previously we were showing + stuff like FirewallOptions objects. To make sure that dynamic + group expansion is done the same way in the UI and for the + compiler, also fixed #2502 (consolidate logic for DynamicGroup). + 2011-07-11 theron * Implemented #2514, support for address table alternate paths. There's a "data directory" setting under user preferences. If the diff --git a/src/libfwbuilder/src/fwbuilder/DynamicGroup.cpp b/src/libfwbuilder/src/fwbuilder/DynamicGroup.cpp index 815c0cde7..46d4f43a7 100644 --- a/src/libfwbuilder/src/fwbuilder/DynamicGroup.cpp +++ b/src/libfwbuilder/src/fwbuilder/DynamicGroup.cpp @@ -26,15 +26,16 @@ #include #include #include +#include #include using namespace std; using namespace libfwbuilder; -#define TYPE_NONE "none" -#define TYPE_ANY "any" -#define KEYWORD_NONE "," -#define KEYWORD_ANY "" +const char *DynamicGroup::TYPE_NONE = "none"; +const char *DynamicGroup::TYPE_ANY = "any"; +const char *DynamicGroup::KEYWORD_NONE = ","; +const char *DynamicGroup::KEYWORD_ANY = ""; const char *DynamicGroup::TYPENAME={"DynamicGroup"}; @@ -153,20 +154,59 @@ void DynamicGroup::loadFromSource(bool ipv6, FWOptions *options, bool test_mode) FWObject *elem = (*tree_iter); if (elem == root) continue; - const set &keywords = elem->getKeywords(); - - list::const_iterator iter; - for (iter = m_filter.begin(); iter != m_filter.end(); ++iter) { - string type, keyword; - splitFilter(*iter, type, keyword); - - if ((type == TYPE_ANY || elem->getTypeName() == type) && - (keyword == KEYWORD_ANY || keywords.count(keyword) > 0)) { - addRef(elem); - break; - } - } - + if (!isMemberOfGroup(elem)) continue; + addRef(elem); } - +} + + +static bool isInDeletedObjs(FWObject *obj) +{ + for ( ; ; ) { + obj = obj->getParent(); + if (obj == 0) return false; + if (obj->getId() == FWObjectDatabase::DELETED_OBJECTS_ID) return true; + } +} + + +static int distanceFromRoot(FWObject *obj) +{ + int count = 0; + while (obj != 0) { + obj = obj->getParent(); + count++; + } + return count; +} + + +bool DynamicGroup::isMemberOfGroup(FWObject *obj) +{ + if (obj == this) return false; + if (ObjectGroup::cast(obj) == 0 && Address::cast(obj) == 0) return false; + if (RuleElement::cast(obj) != 0) return false; + if (isInDeletedObjs(obj)) return false; + + /* There's no way to figure out what are the "standard" object + groups (like "address tables") from within the fwbuilder + library, so we rely on counting how deep we are in the tree + instead. */ + if (ObjectGroup::cast(obj) != 0 && distanceFromRoot(obj) <= 4) return false; + + + const set &keywords = obj->getKeywords(); + + list::const_iterator iter; + for (iter = m_filter.begin(); iter != m_filter.end(); ++iter) { + string type, keyword; + splitFilter(*iter, type, keyword); + + if ((type == TYPE_ANY || obj->getTypeName() == type) && + (keyword == KEYWORD_ANY || keywords.count(keyword) > 0)) { + return true; + } + } + + return false; } diff --git a/src/libfwbuilder/src/fwbuilder/DynamicGroup.h b/src/libfwbuilder/src/fwbuilder/DynamicGroup.h index 459427072..4a008bdda 100644 --- a/src/libfwbuilder/src/fwbuilder/DynamicGroup.h +++ b/src/libfwbuilder/src/fwbuilder/DynamicGroup.h @@ -65,6 +65,13 @@ class DynamicGroup : public MultiAddress * verify whether given object type is approppriate as a child */ virtual bool validateChild(FWObject *o); + + bool isMemberOfGroup(FWObject *obj); + + static const char *TYPE_NONE; + static const char *TYPE_ANY; + static const char *KEYWORD_NONE; + static const char *KEYWORD_ANY; }; } diff --git a/src/libgui/DynamicGroupDialog.cpp b/src/libgui/DynamicGroupDialog.cpp index 3e17e86e3..3bdf89de1 100644 --- a/src/libgui/DynamicGroupDialog.cpp +++ b/src/libgui/DynamicGroupDialog.cpp @@ -36,12 +36,6 @@ using namespace std; using namespace libfwbuilder; -#define TYPE_NONE "none" -#define TYPE_ANY "any" -#define KEYWORD_NONE "," -#define KEYWORD_ANY "" - - DynamicItemDelegate::DynamicItemDelegate(DynamicGroupDialog *dialog, QObject *parent) : QItemDelegate(parent), @@ -92,12 +86,14 @@ void DynamicItemDelegate::setEditorData(QWidget *editor, QComboBox *combo = static_cast(editor); combo->clear(); if (index.column() == 1) { - if (value == TYPE_NONE) { - combo->addItem("None selected", TYPE_NONE); + if (value == DynamicGroup::TYPE_NONE) { + combo->addItem("None selected", DynamicGroup::TYPE_NONE); combo->setCurrentIndex(0); } - combo->addItem("Any type", TYPE_ANY); - if (value == TYPE_ANY) combo->setCurrentIndex(combo->count() - 1); + combo->addItem("Any type", DynamicGroup::TYPE_ANY); + if (value == DynamicGroup::TYPE_ANY) { + combo->setCurrentIndex(combo->count() - 1); + } combo->insertSeparator(2); @@ -109,13 +105,15 @@ void DynamicItemDelegate::setEditorData(QWidget *editor, } } } else if (index.column() == 2) { - if (value == KEYWORD_NONE) { - combo->addItem("None selected", KEYWORD_NONE); + if (value == DynamicGroup::KEYWORD_NONE) { + combo->addItem("None selected", DynamicGroup::KEYWORD_NONE); combo->setCurrentIndex(0); } - combo->addItem("Any keyword", KEYWORD_ANY); - if (value == KEYWORD_ANY) combo->setCurrentIndex(combo->count() - 1); + combo->addItem("Any keyword", DynamicGroup::KEYWORD_ANY); + if (value == DynamicGroup::KEYWORD_ANY) { + combo->setCurrentIndex(combo->count() - 1); + } combo->insertSeparator(2); QStringList list; @@ -276,34 +274,24 @@ void DynamicGroupDialog::loadFWObject(FWObject *o) FWObject *elem = (*tree_iter); if (elem == root) continue; - const set &keywords = elem->getKeywords(); + if (!objGroup->isMemberOfGroup(elem)) continue; - list::const_iterator iter; - for (iter = filter.begin(); iter != filter.end(); ++iter) { - string type, keyword; - objGroup->splitFilter(*iter, type, keyword); + QTreeWidgetItem *item = new QTreeWidgetItem(m_ui.matchedView); + item->setText(0, QString::fromUtf8(elem->getName().c_str())); + item->setText(1, FWObjectPropertiesFactory::getObjectProperties(elem)); + item->setData(0, Qt::UserRole, QVariant(elem->getId())); + QString icon = ":/Icons/"; + icon += elem->getTypeName().c_str(); + icon += "/icon-ref"; - if ((type == TYPE_ANY || elem->getTypeName() == type) && - (keyword == KEYWORD_ANY || keywords.count(keyword) > 0)) { - QTreeWidgetItem *item = new QTreeWidgetItem(m_ui.matchedView); - item->setText(0, QString::fromUtf8(elem->getName().c_str())); - item->setText(1, FWObjectPropertiesFactory::getObjectProperties(elem)); - item->setData(0, Qt::UserRole, QVariant(elem->getId())); - QString icon = ":/Icons/"; - icon += elem->getTypeName().c_str(); - icon += "/icon-ref"; - - QPixmap pixmap; - if (!QPixmapCache::find(icon, pixmap)) { - pixmap.load(icon); - QPixmapCache::insert(icon, pixmap); - } - item->setIcon(0, QIcon(pixmap)); - - m_ui.matchedView->addTopLevelItem(item); - break; - } + QPixmap pixmap; + if (!QPixmapCache::find(icon, pixmap)) { + pixmap.load(icon); + QPixmapCache::insert(icon, pixmap); } + item->setIcon(0, QIcon(pixmap)); + + m_ui.matchedView->addTopLevelItem(item); } } @@ -318,8 +306,8 @@ void DynamicGroupDialog::addMatchClicked() int newRow = m_model->rowCount(); QList items; items << new QStandardItem("") - << new QStandardItem(TYPE_NONE) - << new QStandardItem(KEYWORD_NONE); + << new QStandardItem(DynamicGroup::TYPE_NONE) + << new QStandardItem(DynamicGroup::KEYWORD_NONE); m_model->insertRow(newRow, items); m_ui.criteriaView->openPersistentEditor(m_model->index(newRow, 0));