Fix database corruption when adding a new group while the Backup group exists. Recover orphaned entries. (Bug #2897997)
git-svn-id: https://svn.code.sf.net/p/keepassx/code/trunk@356 b624d157-de02-0410-bad0-e51aec6abb33
This commit is contained in:
		
							parent
							
								
									aa807c9f53
								
							
						
					
					
						commit
						5298bacd05
					
				| 
						 | 
					@ -52,7 +52,7 @@ bool Kdb3Database::StdEntryLessThan(const Kdb3Database::StdEntry& This,const Kdb
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Kdb3Database::Kdb3Database() : RawMasterKey(32), RawMasterKey_CP1252(32),
 | 
					Kdb3Database::Kdb3Database() : File(NULL), RawMasterKey(32), RawMasterKey_CP1252(32),
 | 
				
			||||||
	RawMasterKey_Latin1(32), RawMasterKey_UTF8(32), MasterKey(32){
 | 
						RawMasterKey_Latin1(32), RawMasterKey_UTF8(32), MasterKey(32){
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -448,14 +448,28 @@ bool Kdb3Database::createGroupTree(QList<quint32>& Levels){
 | 
				
			||||||
	for(int i=0;i<Groups.size();i++)EntryIndexCounter << 0;
 | 
						for(int i=0;i<Groups.size();i++)EntryIndexCounter << 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for(int e=0;e<Entries.size();e++){
 | 
						for(int e=0;e<Entries.size();e++){
 | 
				
			||||||
 | 
							int groupIndex = -1;
 | 
				
			||||||
		for(int g=0;g<Groups.size();g++){
 | 
							for(int g=0;g<Groups.size();g++){
 | 
				
			||||||
			if(Entries[e].GroupId==Groups[g].Id){
 | 
								if(Entries[e].GroupId==Groups[g].Id){
 | 
				
			||||||
				Groups[g].Entries.append(&Entries[e]);
 | 
									groupIndex = g;
 | 
				
			||||||
				Entries[e].Group=&Groups[g];
 | 
									break;
 | 
				
			||||||
				Entries[e].Index=EntryIndexCounter[g];
 | 
					 | 
				
			||||||
				EntryIndexCounter[g]++;
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							if (groupIndex == -1) {
 | 
				
			||||||
 | 
								qWarning("Orphaned entry found, assigning to first group");
 | 
				
			||||||
 | 
								for(int g=0;g<Groups.size();g++){
 | 
				
			||||||
 | 
									if(Groups[g].Id == RootGroup.Children[0]->Id){
 | 
				
			||||||
 | 
										groupIndex = g;
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							Groups[groupIndex].Entries.append(&Entries[e]);
 | 
				
			||||||
 | 
							Entries[e].Group=&Groups[groupIndex];
 | 
				
			||||||
 | 
							Entries[e].Index=EntryIndexCounter[groupIndex];
 | 
				
			||||||
 | 
							EntryIndexCounter[groupIndex]++;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
| 
						 | 
					@ -1105,13 +1119,16 @@ IGroupHandle* Kdb3Database::addGroup(const CGroup* group,IGroupHandle* ParentHan
 | 
				
			||||||
		Groups.back().Parent->Children.append(&Groups.back());
 | 
							Groups.back().Parent->Children.append(&Groups.back());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else{
 | 
						else{
 | 
				
			||||||
 | 
							// Insert to root group. Try to keep Backup group at the end.
 | 
				
			||||||
		Groups.back().Parent=&RootGroup;
 | 
							Groups.back().Parent=&RootGroup;
 | 
				
			||||||
		Groups.back().Index=RootGroup.Children.size();
 | 
							Groups.back().Index=RootGroup.Children.size();
 | 
				
			||||||
		if (group->Title!="Backup" && RootGroup.Children.size() && RootGroup.Children.last()->Title=="Backup"){
 | 
							int position = RootGroup.Children.size();
 | 
				
			||||||
 | 
							if (group->Title!="Backup" && !RootGroup.Children.isEmpty() && RootGroup.Children.last()->Title=="Backup"){
 | 
				
			||||||
			RootGroup.Children.last()->Index = Groups.back().Index;
 | 
								RootGroup.Children.last()->Index = Groups.back().Index;
 | 
				
			||||||
			Groups.back().Index--;
 | 
								Groups.back().Index--;
 | 
				
			||||||
 | 
								position--;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		Groups.back().Parent->Children.append(&Groups.back());
 | 
							RootGroup.Children.insert(position, &Groups.back());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return &GroupHandles.back();
 | 
						return &GroupHandles.back();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1136,11 +1153,25 @@ IGroupHandle* Kdb3Database::backupGroup(bool create){
 | 
				
			||||||
	return group;
 | 
						return group;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Kdb3Database::StdEntry::StdEntry(){
 | 
				
			||||||
 | 
						Handle = NULL;
 | 
				
			||||||
 | 
						Group = NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Kdb3Database::StdGroup::StdGroup(){
 | 
				
			||||||
 | 
						Index=0;
 | 
				
			||||||
 | 
						Id=0;
 | 
				
			||||||
 | 
						Parent=NULL;
 | 
				
			||||||
 | 
						Handle=NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Kdb3Database::StdGroup::StdGroup(const CGroup& other){
 | 
					Kdb3Database::StdGroup::StdGroup(const CGroup& other){
 | 
				
			||||||
	Index=0;
 | 
						Index=0;
 | 
				
			||||||
	Id=other.Id;
 | 
						Id=other.Id;
 | 
				
			||||||
	Image=other.Image;
 | 
						Image=other.Image;
 | 
				
			||||||
	Title=other.Title;
 | 
						Title=other.Title;
 | 
				
			||||||
 | 
						Parent=NULL;
 | 
				
			||||||
 | 
						Handle=NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Kdb3Database::EntryHandle::setTitle(const QString& Title){Entry->Title=Title; }
 | 
					void Kdb3Database::EntryHandle::setTitle(const QString& Title){Entry->Title=Title; }
 | 
				
			||||||
| 
						 | 
					@ -1226,6 +1257,7 @@ void Kdb3Database::EntryHandle::setVisualIndex(int index){
 | 
				
			||||||
Kdb3Database::EntryHandle::EntryHandle(Kdb3Database* db){
 | 
					Kdb3Database::EntryHandle::EntryHandle(Kdb3Database* db){
 | 
				
			||||||
	pDB=db;
 | 
						pDB=db;
 | 
				
			||||||
	valid=true;
 | 
						valid=true;
 | 
				
			||||||
 | 
						Entry=NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -117,6 +117,7 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class StdEntry:public CEntry{
 | 
						class StdEntry:public CEntry{
 | 
				
			||||||
		public:
 | 
							public:
 | 
				
			||||||
 | 
									StdEntry();
 | 
				
			||||||
				quint16 Index;
 | 
									quint16 Index;
 | 
				
			||||||
				EntryHandle* Handle;
 | 
									EntryHandle* Handle;
 | 
				
			||||||
				StdGroup* Group;
 | 
									StdGroup* Group;
 | 
				
			||||||
| 
						 | 
					@ -124,7 +125,7 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class StdGroup:public CGroup{
 | 
						class StdGroup:public CGroup{
 | 
				
			||||||
		public:
 | 
							public:
 | 
				
			||||||
			StdGroup():CGroup(){};
 | 
								StdGroup();
 | 
				
			||||||
			StdGroup(const CGroup&);
 | 
								StdGroup(const CGroup&);
 | 
				
			||||||
			quint16 Index;
 | 
								quint16 Index;
 | 
				
			||||||
			StdGroup* Parent;
 | 
								StdGroup* Parent;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue