View Issue Details

IDProjectCategoryView StatusLast Update
0011293ScribusStory Editor / Text Framespublic2013-01-06 03:10
Reportercezaryece Assigned Tojghali  
PriorityhighSeveritymajorReproducibilityalways
Status closedResolutionfixed 
Product Version1.5.0svn 
Fixed in Version1.5.0svn 
Summary0011293: [PATCH] Crash on deleting text with footnotes marks in oveloaded text.
DescriptionWhen marks for footnotes are placed in text which is hidden in overloaded part of text then Scribus crash because of access to not initialized pointers in TextNote class.

Patch against that crash is attached...
TagsNo tags attached.
Patch

Activities

cezaryece

2012-12-27 15:31

updater  

footnotes_fix.diff (5,002 bytes)   
diff --git a/Scribus/scribus/scribusdoc.cpp b/Scribus/scribus/scribusdoc.cpp
index 7f52fa1..0e08c26 100644
--- a/Scribus/scribus/scribusdoc.cpp
+++ b/Scribus/scribus/scribusdoc.cpp
@@ -16735,7 +16735,24 @@ int ScribusDoc::findMarkCPos(Mark* mrk, PageItem* &currItem, int Start)
 	if (currItem == NULL)
 		currItem = findFirstMarkItem(mrk);
 	if (currItem == NULL)
+	{
+		foreach (PageItem* item, DocItems)
+		{
+			if (item->isTextFrame() && (item->prevInChain() == NULL))
+			{
+				for (int pos = 0; pos < item->itemText.length(); ++pos)
+				{
+					ScText* hl = item->itemText.item(pos);
+					if (hl->hasMark(mrk))
+					{
+						currItem = item;
+						return pos;
+					}
+				}
+			}
+		}
 		return -1;
+	}
 	Q_ASSERT(currItem->isTextFrame());
 
 	if (Start < currItem->firstInFrame())
@@ -16940,6 +16957,33 @@ bool ScribusDoc::invalidateVariableTextFrames(Mark* mrk, bool forceUpdate)
 //and update marks list in Marka Manager
 bool ScribusDoc::updateMarks(bool updateNotesMarks)
 {
+	if (updateNotesMarks && !notesList().isEmpty())
+	{
+		foreach (PageItem* item, DocItems)
+		{
+			if (item->isTextFrame() && !item->isNoteFrame())
+			{
+				if (item->prevInChain() == NULL)
+				{
+					item = item->lastInChain();
+					int pos = item->lastInFrame() +1;
+					if (pos < item->itemText.length())
+					{
+						for (int i = pos; i < item->itemText.length(); ++i)
+						{
+							if (item->itemText.item(i)->hasMark() && item->itemText.item(i)->mark->isNoteType())
+							{
+								TextNote * note = item->itemText.item(i)->mark->getNotePtr();
+								note->setNoteMark(NULL);
+								note->masterMark()->setItemPtr(item);
+								note->masterMark()->setItemName(item->itemName());
+							}
+						}
+					}
+				}
+			}
+		}
+	}
 	if (m_docMarksList.isEmpty())
 	{
 		if ((!notesList().isEmpty() || notesChanged()) && updateNotesMarks && !isLoading())
@@ -17184,13 +17228,16 @@ void ScribusDoc::deleteNote(TextNote* note)
 		return;
 	PageItem_NoteFrame* nF = NULL;
 	if (note->noteMark() != NULL)
+	{
 		if (note->noteMark()->getItemPtr() != NULL)
 			nF = note->noteMark()->getItemPtr()->asNoteFrame();
 		if (nF == NULL)
 			nF = findFirstMarkItem(note->noteMark())->asNoteFrame();
-	Q_ASSERT(nF != NULL);
+	}
+	PageItem* master = note->masterMark()->getItemPtr();
+	if (nF)
+	{
 		nF->removeNote(note);
-	PageItem* master = note->masterMark()->getItemPtr();
 		nF->invalid = true;
 		master->invalid = true;
 		if (nF->notesList().isEmpty() && nF->isAutoNoteFrame())
@@ -17198,7 +17245,8 @@ void ScribusDoc::deleteNote(TextNote* note)
 			nF->deleteIt = true;
 			master->asTextFrame()->removeNoteFrame(nF);
 		}
-//	else
+	}
+	//	else
 //		master->asTextFrame()->setNoteFrame(nF);
 	if (note->masterMark() != NULL)
 		eraseMark(note->masterMark(), true, master);
@@ -17212,12 +17260,12 @@ void ScribusDoc::deleteNote(TextNote* note)
 }
 
 void ScribusDoc::setUndoDelNote(TextNote *note)
-{ //used by MarksManager
+{
 	if (UndoManager::undoEnabled())
 	{
 		ScItemsState* ims = new ScItemsState(Um::DeleteNote,"",Um::IDelete);
 		ims->set("DELETE_NOTE", QString("delete_note"));
-		ims->set("ETEA", note->masterMark()->label);
+//		ims->set("ETEA", note->masterMark()->label);
 		PageItem* master = note->masterMark()->getItemPtr();
 		int pos = findMarkCPos(note->masterMark(), master);
 		Q_ASSERT(pos > -1);
@@ -17851,7 +17899,11 @@ PageItem_NoteFrame *ScribusDoc::createNoteFrame(NotesStyle *nStyle, double x, do
 void ScribusDoc::delNoteFrame(PageItem_NoteFrame* nF, bool removeMarks, bool forceDeletion)
 {
 	Q_ASSERT(nF != NULL);
-	//check if note frame is listed in text frames m_notesFramesMap
+
+	//for all notes in noteFrame set notes marks to null
+	foreach(TextNote* n, nF->notesList())
+		n->setNoteMark(NULL);
+
 	if (nF->itemText.length() > 0 && removeMarks)
 		nF->removeMarksFromText(false);
 		
diff --git a/Scribus/scribus/text/storytext.cpp b/Scribus/scribus/text/storytext.cpp
index 40f2310..6a92624 100644
--- a/Scribus/scribus/text/storytext.cpp
+++ b/Scribus/scribus/text/storytext.cpp
@@ -1959,11 +1959,13 @@ void StoryText::saxx(SaxHandler& handler, const Xml_string& elemtag) const
 			}
 			else if (mrk->isType(MARKNoteMasterType))
 			{
-				mark_attr.insert("nStyle", mrk->getNotePtr()->notesStyle()->name());
-				mark_attr.insert("note",mrk->getNotePtr()->saxedText());
+				TextNote * note = mrk->getNotePtr();
+				assert(note != null);
+				mark_attr.insert("nStyle", note->notesStyle()->name());
+				mark_attr.insert("note",note->saxedText());
 				//store noteframe name for inserting into note if it is non-auto-removable
-				if (!mrk->getNotePtr()->noteMark()->getItemPtr()->isAutoNoteFrame())
-					mark_attr.insert("noteframe", mrk->getNotePtr()->noteMark()->getItemPtr()->getUName());
+				if (note->noteMark() && note->noteMark()->getItemPtr() && !note->noteMark()->getItemPtr()->isAutoNoteFrame())
+					mark_attr.insert("noteframe", note->noteMark()->getItemPtr()->getUName());
 			}
 			handler.beginEnd("mark", mark_attr);
 		}
footnotes_fix.diff (5,002 bytes)   

jghali

2012-12-27 16:17

administrator   ~0029495

Unfortunately the patch does not apply to current trunk.

cezaryece

2013-01-03 09:22

updater  

footnotes_fix.patch (5,063 bytes)   
diff --git a/Scribus/scribus/scribusdoc.cpp b/Scribus/scribus/scribusdoc.cpp
index d67137f..5a58a73 100644
--- a/Scribus/scribus/scribusdoc.cpp
+++ b/Scribus/scribus/scribusdoc.cpp
@@ -16763,7 +16763,24 @@ int ScribusDoc::findMarkCPos(Mark* mrk, PageItem* &currItem, int Start)
 	if (currItem == NULL)
 		currItem = findFirstMarkItem(mrk);
 	if (currItem == NULL)
+	{
+		foreach (PageItem* item, DocItems)
+		{
+			if (item->isTextFrame() && (item->prevInChain() == NULL))
+			{
+				for (int pos = 0; pos < item->itemText.length(); ++pos)
+				{
+					ScText* hl = item->itemText.item(pos);
+					if (hl->hasMark(mrk))
+					{
+						currItem = item;
+						return pos;
+					}
+				}
+			}
+		}
 		return -1;
+	}
 	Q_ASSERT(currItem->isTextFrame());
 
 	if (Start < currItem->firstInFrame())
@@ -16968,6 +16985,33 @@ bool ScribusDoc::invalidateVariableTextFrames(Mark* mrk, bool forceUpdate)
 //and update marks list in Marka Manager
 bool ScribusDoc::updateMarks(bool updateNotesMarks)
 {
+	if (updateNotesMarks && !notesList().isEmpty())
+	{
+		foreach (PageItem* item, DocItems)
+		{
+			if (item->isTextFrame() && !item->isNoteFrame())
+			{
+				if (item->prevInChain() == NULL)
+				{
+					item = item->lastInChain();
+					int pos = item->lastInFrame() +1;
+					if (pos < item->itemText.length())
+					{
+						for (int i = pos; i < item->itemText.length(); ++i)
+						{
+							if (item->itemText.item(i)->hasMark() && item->itemText.item(i)->mark->isNoteType())
+							{
+								TextNote * note = item->itemText.item(i)->mark->getNotePtr();
+								note->setNoteMark(NULL);
+								note->masterMark()->setItemPtr(item);
+								note->masterMark()->setItemName(item->itemName());
+							}
+						}
+					}
+				}
+			}
+		}
+	}
 	if (m_docMarksList.isEmpty())
 	{
 		if ((!notesList().isEmpty() || notesChanged()) && updateNotesMarks && !isLoading())
@@ -17212,22 +17256,24 @@ void ScribusDoc::deleteNote(TextNote* note)
 		return;
 	PageItem_NoteFrame* nF = NULL;
 	if (note->noteMark() != NULL)
+	{
 		if (note->noteMark()->getItemPtr() != NULL)
 			nF = note->noteMark()->getItemPtr()->asNoteFrame();
 	if (nF == NULL)
 		nF = findFirstMarkItem(note->noteMark())->asNoteFrame();
-	Q_ASSERT(nF != NULL);
-	nF->removeNote(note);
+	}
 	PageItem* master = note->masterMark()->getItemPtr();
-	nF->invalid = true;
-	master->invalid = true;
-	if (nF->notesList().isEmpty() && nF->isAutoNoteFrame())
+	if (nF != NULL)
 	{
-		nF->deleteIt = true;
-		master->asTextFrame()->removeNoteFrame(nF);
+		nF->removeNote(note);
+		nF->invalid = true;
+		master->invalid = true;
+		if (nF->notesList().isEmpty() && nF->isAutoNoteFrame())
+		{
+			nF->deleteIt = true;
+			master->asTextFrame()->removeNoteFrame(nF);
+		}
 	}
-//	else
-//		master->asTextFrame()->setNoteFrame(nF);
 	if (note->masterMark() != NULL)
 		eraseMark(note->masterMark(), true, master);
 	if (note->noteMark() != NULL)
@@ -17240,12 +17286,11 @@ void ScribusDoc::deleteNote(TextNote* note)
 }
 
 void ScribusDoc::setUndoDelNote(TextNote *note)
-{ //used by MarksManager
+{
 	if (UndoManager::undoEnabled())
 	{
 		ScItemsState* ims = new ScItemsState(Um::DeleteNote,"",Um::IDelete);
 		ims->set("DELETE_NOTE", QString("delete_note"));
-		ims->set("ETEA", note->masterMark()->label);
 		PageItem* master = note->masterMark()->getItemPtr();
 		int pos = findMarkCPos(note->masterMark(), master);
 		Q_ASSERT(pos > -1);
@@ -17879,7 +17924,11 @@ PageItem_NoteFrame *ScribusDoc::createNoteFrame(NotesStyle *nStyle, double x, do
 void ScribusDoc::delNoteFrame(PageItem_NoteFrame* nF, bool removeMarks, bool forceDeletion)
 {
 	Q_ASSERT(nF != NULL);
-	//check if note frame is listed in text frames m_notesFramesMap
+
+	//for all notes in noteFrame set notes marks to null
+	foreach(TextNote* n, nF->notesList())
+		n->setNoteMark(NULL);
+
 	if (nF->itemText.length() > 0 && removeMarks)
 		nF->removeMarksFromText(false);
 		
diff --git a/Scribus/scribus/text/storytext.cpp b/Scribus/scribus/text/storytext.cpp
index 40f2310..6a92624 100644
--- a/Scribus/scribus/text/storytext.cpp
+++ b/Scribus/scribus/text/storytext.cpp
@@ -1959,11 +1959,13 @@ void StoryText::saxx(SaxHandler& handler, const Xml_string& elemtag) const
 			}
 			else if (mrk->isType(MARKNoteMasterType))
 			{
-				mark_attr.insert("nStyle", mrk->getNotePtr()->notesStyle()->name());
-				mark_attr.insert("note",mrk->getNotePtr()->saxedText());
+				TextNote * note = mrk->getNotePtr();
+				assert(note != null);
+				mark_attr.insert("nStyle", note->notesStyle()->name());
+				mark_attr.insert("note",note->saxedText());
 				//store noteframe name for inserting into note if it is non-auto-removable
-				if (!mrk->getNotePtr()->noteMark()->getItemPtr()->isAutoNoteFrame())
-					mark_attr.insert("noteframe", mrk->getNotePtr()->noteMark()->getItemPtr()->getUName());
+				if (note->noteMark() && note->noteMark()->getItemPtr() && !note->noteMark()->getItemPtr()->isAutoNoteFrame())
+					mark_attr.insert("noteframe", note->noteMark()->getItemPtr()->getUName());
 			}
 			handler.beginEnd("mark", mark_attr);
 		}
footnotes_fix.patch (5,063 bytes)   

cezaryece

2013-01-03 09:23

updater   ~0029587

New file is against current trunk. Check if can be applied.

jghali

2013-01-03 12:17

administrator   ~0029589

The new patch applies cleanly. Thanks!

jghali

2013-01-03 19:37

administrator   ~0029591

Committed!

christoph_s

2013-01-06 03:10

administrator   ~0029608

Tested, fixed. Thanks.

Issue History

Date Modified Username Field Change
2012-12-27 15:31 cezaryece New Issue
2012-12-27 15:31 cezaryece File Added: footnotes_fix.diff
2012-12-27 16:17 jghali Note Added: 0029495
2012-12-31 09:49 cezaryece Summary Crash on deleting text with footnotes marks in oveloaded text. => [PATCH] Crash on deleting text with footnotes marks in oveloaded text.
2013-01-03 09:22 cezaryece File Added: footnotes_fix.patch
2013-01-03 09:23 cezaryece Note Added: 0029587
2013-01-03 12:17 jghali Note Added: 0029589
2013-01-03 19:37 jghali Note Added: 0029591
2013-01-03 19:37 jghali Status new => resolved
2013-01-03 19:37 jghali Fixed in Version => 1.5.0svn
2013-01-03 19:37 jghali Resolution open => fixed
2013-01-03 19:37 jghali Assigned To => jghali
2013-01-06 03:10 christoph_s Note Added: 0029608
2013-01-06 03:10 christoph_s Status resolved => closed
2015-09-17 20:08 Kunda Category Story Editor / Text Frames => Story Ed/Txt Frames
2015-09-17 20:12 Kunda Category Story Ed/Txt Frames => Story Editor / Text Frames