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