r21535 by jghali - #14380 / #14129 backport: Crash caused by incorrect handling of reference to deleted styles by style manager

scribus-commit scribus-commit at lists.scribus.net
Mon Nov 21 23:34:51 UTC 2016


Author: jghali
Date: Mon Nov 21 23:34:51 2016
New Revision: 21535

URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=21535
Log:
#14380 / #14129 backport: Crash caused by incorrect handling of reference to deleted styles by style manager

Modified:
    branches/Version14x/Scribus/scribus/scribus.cpp
    branches/Version14x/Scribus/scribus/smtextstyles.cpp
    branches/Version14x/Scribus/scribus/smtextstyles.h
    branches/Version14x/Scribus/scribus/style.h
    branches/Version14x/Scribus/scribus/styles/style.cpp

Modified: branches/Version14x/Scribus/scribus/scribus.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21535&path=/branches/Version14x/Scribus/scribus/scribus.cpp
==============================================================================
--- branches/Version14x/Scribus/scribus/scribus.cpp	(original)
+++ branches/Version14x/Scribus/scribus/scribus.cpp	Mon Nov 21 23:34:51 2016
@@ -519,7 +519,7 @@
 	// initializing style manager here too even it's not strictly a palette
 	styleManager = new StyleManager(this, "styleManager");
 	SMCharacterStyle *tmpCS = new SMCharacterStyle();
-	styleManager->addStyle(new SMParagraphStyle(tmpCS->tmpStyles()));
+	styleManager->addStyle(new SMParagraphStyle(tmpCS));
 	styleManager->addStyle(tmpCS);
 	styleManager->addStyle(new SMLineStyle());
 	connect( scrActions["editStyles"], SIGNAL(toggled(bool)), styleManager, SLOT(setPaletteShown(bool)) );

Modified: branches/Version14x/Scribus/scribus/smtextstyles.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21535&path=/branches/Version14x/Scribus/scribus/smtextstyles.cpp
==============================================================================
--- branches/Version14x/Scribus/scribus/smtextstyles.cpp	(original)
+++ branches/Version14x/Scribus/scribus/smtextstyles.cpp	Mon Nov 21 23:34:51 2016
@@ -38,10 +38,11 @@
 #include "util.h"
 
 
-SMParagraphStyle::SMParagraphStyle(StyleSet<CharStyle> *cstyles) : StyleItem(),
-pwidget_(0), doc_(0), selectionIsDirty_(false), unitRatio_(1.0), cstyles_(cstyles)
-{
-	Q_ASSERT(cstyles_);
+SMParagraphStyle::SMParagraphStyle(SMCharacterStyle* cstyleItem) : StyleItem(),
+pwidget_(0), doc_(0), selectionIsDirty_(false), unitRatio_(1.0), cstyleItem_(cstyleItem)
+{
+	Q_ASSERT(cstyleItem_);
+	cstyles_ = cstyleItem_->tmpStyles();
 	pwidget_ = new SMPStyleWidget();
 	Q_CHECK_PTR(pwidget_);
 }
@@ -403,6 +404,35 @@
 			tmpStyles_.remove(index);
 
 		deleted_.append(removeList[i]);
+	}
+
+	// Check other paragraph styles and replace inherited styles if necessary
+	for (int i = 0; i < tmpStyles_.count(); ++i)
+	{
+		ParagraphStyle& parStyle = tmpStyles_[i];
+		QString parentName = parStyle.parent();
+		if (parentName.isEmpty())
+			continue;
+
+		QString replacementName = parentName;
+		for (int j = 0; j < removeList.count(); ++j)
+		{
+			if (removeList.at(j).first == parentName)
+			{
+				replacementName = removeList.at(j).second;
+				break;
+			}
+		}
+
+		if (replacementName == parentName)
+			continue;
+		if (replacementName == CommonStrings::trDefaultParagraphStyle)
+			replacementName = CommonStrings::DefaultParagraphStyle;
+		if (!parStyle.canInherit(replacementName))
+			replacementName = QString();
+		if (!replacementName.isEmpty() && (tmpStyles_.find(replacementName) < 0))
+			replacementName = QString();
+		parStyle.setParent(replacementName);
 	}
 }
 
@@ -554,6 +584,9 @@
 	connect(pwidget_->cpage->baselineOffset_, SIGNAL(valueChanged(double)), this, SLOT(slotBaselineOffset()));
 	connect(pwidget_->cpage->parentCombo, SIGNAL(activated(const QString&)),
 			this, SLOT(slotCharParentChanged(const QString&)));
+
+	// Referenced character style changes
+	connect(cstyleItem_, SIGNAL(charStylesDeleted(const QList<RemoveItem>&)), this, SLOT(slotCharStylesDeleted(const QList<RemoveItem>&)));
 }
 
 void SMParagraphStyle::removeConnections()
@@ -623,6 +656,8 @@
 	disconnect(pwidget_->cpage->baselineOffset_, SIGNAL(valueChanged(double)), this, SLOT(slotBaselineOffset()));
 	disconnect(pwidget_->cpage->parentCombo, SIGNAL(activated(const QString&)),
 			this, SLOT(slotCharParentChanged(const QString&)));
+
+	disconnect(cstyleItem_, SIGNAL(charStylesDeleted(const QList<RemoveItem>&)), this, SLOT(slotCharStylesDeleted(const QList<RemoveItem>&)));
 }
 
 void SMParagraphStyle::slotLineSpacingMode(int mode)
@@ -1422,6 +1457,31 @@
 	}
 }
 
+void SMParagraphStyle::slotCharStylesDeleted(const QList<RemoveItem> &removeList)
+{
+	for (int i = 0; i < tmpStyles_.count(); ++i)
+	{
+		ParagraphStyle& parStyle = tmpStyles_[i];
+
+		QString charStyleName = parStyle.charStyle().parent();
+		if (!charStyleName.isEmpty())
+		{
+			for (int j = 0; j < removeList.count(); ++j)
+			{
+				const RemoveItem& rmItem = removeList.at(j);
+				if (charStyleName == rmItem.first)
+				{
+					QString replacementName = rmItem.second;
+					if (rmItem.second == CommonStrings::trDefaultCharacterStyle)
+						replacementName = CommonStrings::DefaultCharacterStyle;
+					parStyle.charStyle().setParent(replacementName);
+					break;
+				}
+			}
+		}
+	}
+}
+
 SMParagraphStyle::~SMParagraphStyle()
 {
 
@@ -1767,6 +1827,39 @@
 			tmpStyles_.remove(index);
 		deleted_ << removeList[i];
 	}
+
+	// Check other character styles and replace inherited styles if necessary
+	for (int i = 0; i < tmpStyles_.count(); ++i)
+	{
+		CharStyle& charStyle = tmpStyles_[i];
+		QString parentName = charStyle.parent();
+		if (parentName.isEmpty())
+			continue;
+
+		QString replacementName = parentName;
+		for (int j = 0; j < removeList.count(); ++j)
+		{
+			if (removeList.at(j).first == parentName)
+			{
+				replacementName = removeList.at(j).second;
+				break;
+			}
+		}
+
+		if (replacementName == parentName)
+			continue;
+		if (replacementName == CommonStrings::trDefaultCharacterStyle)
+			replacementName = CommonStrings::DefaultCharacterStyle;
+		if (!charStyle.canInherit(replacementName))
+			replacementName = QString();
+		if (!replacementName.isEmpty() && (tmpStyles_.find(replacementName) < 0))
+			replacementName = QString();
+		charStyle.setParent(replacementName);
+	}
+
+	emit charStylesDeleted(removeList);
+
+	emit charStylesDeleted(removeList);
 }
 
 void SMCharacterStyle::nameChanged(const QString &newName)
@@ -1808,7 +1901,12 @@
 	}
 
 	if (oldName != newName)
+	{
 		deleted_.append(RemoveItem(oldName, newName));
+		QList<RemoveItem> deletedStyles;
+		deletedStyles.append(RemoveItem(oldName, newName));
+		emit charStylesDeleted(deletedStyles);
+	}
 
 	if (!selectionIsDirty_)
 	{

Modified: branches/Version14x/Scribus/scribus/smtextstyles.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21535&path=/branches/Version14x/Scribus/scribus/smtextstyles.h
==============================================================================
--- branches/Version14x/Scribus/scribus/smtextstyles.h	(original)
+++ branches/Version14x/Scribus/scribus/smtextstyles.h	Mon Nov 21 23:34:51 2016
@@ -16,12 +16,13 @@
 class ScribusDoc;
 class SMCStyleWidget;
 class SMPStyleWidget;
+class SMCharacterStyle;
 
 class SMParagraphStyle : public StyleItem
 {
 	Q_OBJECT
 public:
-	SMParagraphStyle(StyleSet<CharStyle> *cstyles);
+	SMParagraphStyle(SMCharacterStyle* cstyleItem);
 	~SMParagraphStyle();
 
 	QTabWidget* widget();
@@ -53,6 +54,7 @@
 
 private:
 	SMPStyleWidget *pwidget_;
+	SMCharacterStyle *cstyleItem_;
 	ScribusDoc *doc_;
 	bool selectionIsDirty_;
 	double unitRatio_;
@@ -105,6 +107,7 @@
 	void slotFont(QString s);
 	void slotParentChanged(const QString &parent);
 	void slotCharParentChanged(const QString &parent);
+	void slotCharStylesDeleted(const QList<RemoveItem> &removeList);
 };
 
 class SMCharacterStyle : public StyleItem
@@ -140,6 +143,7 @@
 
 signals:
 	void selectionDirty();
+	void charStylesDeleted(const QList<RemoveItem> &removeList);
 
 private:
 	QTabWidget   *widget_;

Modified: branches/Version14x/Scribus/scribus/style.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21535&path=/branches/Version14x/Scribus/scribus/style.h
==============================================================================
--- branches/Version14x/Scribus/scribus/style.h	(original)
+++ branches/Version14x/Scribus/scribus/style.h	Mon Nov 21 23:34:51 2016
@@ -96,6 +96,8 @@
 	void setParent(const QString& p);
 	bool hasParent() const           { return ! m_parent.isEmpty(); }
 	const Style* parentStyle() const;
+
+	bool canInherit(const QString& parentName) const;
 	
 	static const QString INHERIT_PARENT;
 	

Modified: branches/Version14x/Scribus/scribus/styles/style.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21535&path=/branches/Version14x/Scribus/scribus/styles/style.cpp
==============================================================================
--- branches/Version14x/Scribus/scribus/styles/style.cpp	(original)
+++ branches/Version14x/Scribus/scribus/styles/style.cpp	Mon Nov 21 23:34:51 2016
@@ -77,6 +77,32 @@
 	if (par == this) return NULL; else return par;
 }
 
+bool Style::canInherit(const QString& parentName) const
+{
+	if (m_name.isEmpty() || parentName.isEmpty())
+		return true;
+	if (!m_context || (m_name == parentName))
+		return false;
+
+	const Style* parentStyle = m_context->resolve(parentName);
+	if (!parentStyle)
+		return false;
+
+	bool  loop = false, parentLoop = false;
+
+	const Style* pStyle = parentStyle;
+	while (pStyle)
+	{
+		if (pStyle->hasParent() && (pStyle->parent() == m_name))
+		{
+			loop = parentLoop = true;
+			break;
+		}
+		pStyle = pStyle->hasParent() ? pStyle->parentStyle() : NULL;
+	}
+
+	return (!parentLoop);
+}
 
 void Style::saxxAttributes(Xml_attr& attr) const
 {




More information about the scribus-commit mailing list