diff options
author | Chris Wilson <chris+github@qwirx.com> | 2013-08-22 00:28:23 +0000 |
---|---|---|
committer | Chris Wilson <chris+github@qwirx.com> | 2013-08-22 00:28:23 +0000 |
commit | 711ac679ce0788ec778986dbc377b344a2e25d01 (patch) | |
tree | 13abcbcf0e564f061c7e5e81c8fbbccf61407081 /lib/backupstore | |
parent | 576e90ce3f50e1b9de2bfd6d88736a16604ae552 (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/backupstore')
-rw-r--r-- | lib/backupstore/BackupStoreCheck2.cpp | 15 |
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 { |