summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChris Wilson <chris+github@qwirx.com>2013-08-22 00:28:23 +0000
committerChris Wilson <chris+github@qwirx.com>2013-08-22 00:28:23 +0000
commit711ac679ce0788ec778986dbc377b344a2e25d01 (patch)
tree13abcbcf0e564f061c7e5e81c8fbbccf61407081 /lib
parent576e90ce3f50e1b9de2bfd6d88736a16604ae552 (diff)
Fix a bug where bbstoreaccounts check could hang or crash.
It's not safe to use an iterator after the underlying collection has been modified. We need to restart iterating over the directory in that case. Otherwise we could loop forever looking for an end() that we've already passed, or start accessing unallocated memory.
Diffstat (limited to 'lib')
-rw-r--r--lib/backupstore/BackupStoreCheck2.cpp15
1 files changed, 11 insertions, 4 deletions
diff --git a/lib/backupstore/BackupStoreCheck2.cpp b/lib/backupstore/BackupStoreCheck2.cpp
index 8d633895..19c79304 100644
--- a/lib/backupstore/BackupStoreCheck2.cpp
+++ b/lib/backupstore/BackupStoreCheck2.cpp
@@ -706,7 +706,12 @@ bool BackupStoreDirectory::CheckAndFix()
bool changed = false;
// Check that if a file depends on a new version, that version is in this directory
+ bool restart;
+
+ do
{
+ restart = false;
+
std::vector<Entry*>::iterator i(mEntries.begin());
for(; i != mEntries.end(); ++i)
{
@@ -717,7 +722,7 @@ bool BackupStoreDirectory::CheckAndFix()
if(newerEn == 0)
{
// Depends on something, but it isn't there.
- BOX_TRACE("Entry id " << FMT_i <<
+ BOX_WARNING("Entry id " << FMT_i <<
" removed because depends "
"on newer version " <<
FMT_OID(dependsNewer) <<
@@ -727,11 +732,12 @@ bool BackupStoreDirectory::CheckAndFix()
delete *i;
mEntries.erase(i);
- // Start again at the beginning of the vector, the iterator is now invalid
- i = mEntries.begin();
-
// Mark as changed
changed = true;
+
+ // Start again at the beginning of the vector, the iterator is now invalid
+ restart = true;
+ break;
}
else
{
@@ -753,6 +759,7 @@ bool BackupStoreDirectory::CheckAndFix()
}
}
}
+ while(restart);
// Check that if a file has a dependency marked, it exists, and remove it if it doesn't
{