diff --git a/dom/system/gonk/MozMtpDatabase.cpp b/dom/system/gonk/MozMtpDatabase.cpp index f090b8dbc097..97ac359edc20 100644 --- a/dom/system/gonk/MozMtpDatabase.cpp +++ b/dom/system/gonk/MozMtpDatabase.cpp @@ -171,9 +171,29 @@ void MozMtpDatabase::RemoveEntry(MtpObjectHandle aHandle) { MutexAutoLock lock(mMutex); + if (!IsValidHandle(aHandle)) { + return; + } - if (aHandle > 0 && aHandle < mDb.Length()) { - mDb[aHandle] = nullptr; + RefPtr removedEntry = mDb[aHandle]; + mDb[aHandle] = nullptr; + MTP_DBG("0x%08x removed", aHandle); + // if the entry is not a folder, just return. + if (removedEntry->mObjectFormat != MTP_FORMAT_ASSOCIATION) { + return; + } + + // Find out and remove the children of aHandle. + // Since the index for a directory will always be less than the index of any of its children, + // we can remove the entire subtree in one pass. + ProtectedDbArray::size_type numEntries = mDb.Length(); + ProtectedDbArray::index_type entryIndex; + for (entryIndex = aHandle+1; entryIndex < numEntries; entryIndex++) { + RefPtr entry = mDb[entryIndex]; + if (entry && IsValidHandle(entry->mParent) && !mDb[entry->mParent]) { + mDb[entryIndex] = nullptr; + MTP_DBG("0x%08x removed", aHandle); + } } } diff --git a/dom/system/gonk/MozMtpDatabase.h b/dom/system/gonk/MozMtpDatabase.h index 6d8e35737a77..cf4bce542b9c 100644 --- a/dom/system/gonk/MozMtpDatabase.h +++ b/dom/system/gonk/MozMtpDatabase.h @@ -226,6 +226,11 @@ private: MatchParentFormat, }; + bool IsValidHandle(MtpObjectHandle aHandle) + { + return aHandle > 0 && aHandle < mDb.Length(); + } + void AddEntry(DbEntry* aEntry); void AddEntryAndNotify(DbEntry* aEntr, RefCountedMtpServer* aMtpServer); void DumpEntries(const char* aLabel);