From 2e7b5f9e185297670adc17f3aada0a4af6a48838 Mon Sep 17 00:00:00 2001 From: Hamish Morrison Date: Sat, 26 Jan 2013 19:23:34 +0000 Subject: [PATCH] NetworkCookieJar: don't leak a new cookie if it has expired --- .../network/libnetapi/NetworkCookieJar.cpp | 188 +++++++++--------- 1 file changed, 93 insertions(+), 95 deletions(-) diff --git a/src/kits/network/libnetapi/NetworkCookieJar.cpp b/src/kits/network/libnetapi/NetworkCookieJar.cpp index eef91d110b..5b8a94583b 100644 --- a/src/kits/network/libnetapi/NetworkCookieJar.cpp +++ b/src/kits/network/libnetapi/NetworkCookieJar.cpp @@ -20,14 +20,14 @@ const char* kArchivedCookieMessageName = "be:cookie"; BNetworkCookieJar::BNetworkCookieJar() - : + : fCookieHashMap(new PrivateHashMap) { } BNetworkCookieJar::BNetworkCookieJar(const BNetworkCookieJar&) - : + : BArchivable(), fCookieHashMap(new PrivateHashMap) { @@ -36,7 +36,7 @@ BNetworkCookieJar::BNetworkCookieJar(const BNetworkCookieJar&) BNetworkCookieJar::BNetworkCookieJar(const BNetworkCookieList& otherList) - : + : fCookieHashMap(new PrivateHashMap) { AddCookies(otherList); @@ -44,18 +44,18 @@ BNetworkCookieJar::BNetworkCookieJar(const BNetworkCookieList& otherList) BNetworkCookieJar::BNetworkCookieJar(BMessage* archive) - : + : fCookieHashMap(new PrivateHashMap) { BMessage extractedCookie; - + for (int32 i = 0; archive->FindMessage(kArchivedCookieMessageName, i, &extractedCookie) == B_OK; i++) { - BNetworkCookie* heapCookie + BNetworkCookie* heapCookie = new(std::nothrow) BNetworkCookie(&extractedCookie); - + if (heapCookie == NULL || !AddCookie(heapCookie)) break; } @@ -65,7 +65,7 @@ BNetworkCookieJar::BNetworkCookieJar(BMessage* archive) BNetworkCookieJar::~BNetworkCookieJar() { BNetworkCookie* cookiePtr; - + for (Iterator it(GetIterator()); (cookiePtr = it.Next()); ) delete it.Remove(); } @@ -78,12 +78,12 @@ bool BNetworkCookieJar::AddCookie(const BNetworkCookie& cookie) { BNetworkCookie* heapCookie = new(std::nothrow) BNetworkCookie(cookie); - + if (!AddCookie(heapCookie)) { delete heapCookie; return false; } - + return true; } @@ -91,29 +91,27 @@ BNetworkCookieJar::AddCookie(const BNetworkCookie& cookie) bool BNetworkCookieJar::AddCookie(BNetworkCookie* cookie) { - if (cookie != NULL) { - HashString key(cookie->Domain()); - - if (!fCookieHashMap->fHashMap.ContainsKey(key)) - fCookieHashMap->fHashMap.Put(key, new BList); - - BNetworkCookieList* list = fCookieHashMap->fHashMap.Get(key); - - for (int32 i = 0; i < list->CountItems(); i++) { - BNetworkCookie* c - = reinterpret_cast(list->ItemAt(i)); - - if (c->Name() == cookie->Name()) { - list->RemoveItem(i); - break; - } + if (cookie == NULL || cookie->ShouldDeleteNow()) + return false; + + HashString key(cookie->Domain()); + + if (!fCookieHashMap->fHashMap.ContainsKey(key)) + fCookieHashMap->fHashMap.Put(key, new BList); + + BNetworkCookieList* list = fCookieHashMap->fHashMap.Get(key); + + for (int32 i = 0; i < list->CountItems(); i++) { + BNetworkCookie* c + = reinterpret_cast(list->ItemAt(i)); + + if (c->Name() == cookie->Name()) { + list->RemoveItem(i); + break; } - - // Discard the cookie if it's to be deleted - if (!cookie->ShouldDeleteNow()) - list->AddItem(cookie); } - + + list->AddItem(cookie); return true; } @@ -122,15 +120,15 @@ bool BNetworkCookieJar::AddCookies(const BNetworkCookieList& cookies) { for (int32 i = 0; i < cookies.CountItems(); i++) { - BNetworkCookie* cookiePtr + BNetworkCookie* cookiePtr = reinterpret_cast(cookies.ItemAt(i)); - + // Using AddCookie by reference in order to avoid multiple // cookie jar share the same cookie pointers if (!AddCookie(*cookiePtr)) return false; } - + return true; } @@ -143,8 +141,8 @@ BNetworkCookieJar::DeleteOutdatedCookies() { int32 deleteCount = 0; BNetworkCookie* cookiePtr; - - for (Iterator it(GetIterator()); (cookiePtr = it.Next()); ) { + + for (Iterator it = GetIterator(); (cookiePtr = it.Next()) != NULL;) { if (cookiePtr->ShouldDeleteNow()) { delete it.Remove(); deleteCount++; @@ -160,8 +158,8 @@ BNetworkCookieJar::PurgeForExit() { int32 deleteCount = 0; BNetworkCookie* cookiePtr; - - for (Iterator it(GetIterator()); (cookiePtr = it.Next()); ) { + + for (Iterator it = GetIterator(); (cookiePtr = it.Next()) != NULL;) { if (cookiePtr->ShouldDeleteAtExit()) { delete it.Remove(); deleteCount++; @@ -182,10 +180,10 @@ BNetworkCookieJar::Archive(BMessage* into, bool deep) const if (error == B_OK) { BNetworkCookie* cookiePtr; - - for (Iterator it(GetIterator()); (cookiePtr = it.Next()); ) { + + for (Iterator it = GetIterator(); (cookiePtr = it.Next()) != NULL;) { BMessage subArchive; - + error = cookiePtr->Archive(&subArchive, deep); if (error != B_OK) return error; @@ -205,7 +203,7 @@ BNetworkCookieJar::Instantiate(BMessage* archive) { if (archive->HasMessage(kArchivedCookieMessageName)) return new(std::nothrow) BNetworkCookieJar(archive); - + return NULL; } @@ -242,11 +240,11 @@ BNetworkCookieJar::Flatten(void* buffer, ssize_t size) const { if (FlattenedSize() > size) return B_ERROR; - - fFlattened.CopyInto(reinterpret_cast(buffer), 0, + + fFlattened.CopyInto(reinterpret_cast(buffer), 0, fFlattened.Length()); reinterpret_cast(buffer)[fFlattened.Length()] = 0; - + return B_OK; } @@ -262,13 +260,13 @@ BNetworkCookieJar::AllowsTypeCode(type_code) const status_t BNetworkCookieJar::Unflatten(type_code, const void* buffer, ssize_t size) { - BString flattenedCookies; + BString flattenedCookies; flattenedCookies.SetTo(reinterpret_cast(buffer), size); - - while (flattenedCookies.Length() > 0) { + + while (flattenedCookies.Length() > 0) { BNetworkCookie tempCookie; BString tempCookieLine; - + int32 endOfLine = flattenedCookies.FindFirst('\n', 0); if (endOfLine == -1) tempCookieLine = flattenedCookies; @@ -276,11 +274,11 @@ BNetworkCookieJar::Unflatten(type_code, const void* buffer, ssize_t size) flattenedCookies.MoveInto(tempCookieLine, 0, endOfLine); flattenedCookies.Remove(0, 1); } - + if (tempCookieLine.Length() != 0 && tempCookieLine[0] != '#') { for (int32 field = 0; field < 7; field++) { BString tempString; - + int32 endOfField = tempCookieLine.FindFirst('\t', 0); if (endOfField == -1) tempString = tempCookieLine; @@ -288,42 +286,42 @@ BNetworkCookieJar::Unflatten(type_code, const void* buffer, ssize_t size) tempCookieLine.MoveInto(tempString, 0, endOfField); tempCookieLine.Remove(0, 1); } - + switch (field) { case 0: tempCookie.SetDomain(tempString); break; - + case 1: // TODO: Useless field ATM break; - + case 2: tempCookie.SetPath(tempString); break; - + case 3: tempCookie.SetSecure(tempString == "TRUE"); break; - + case 4: tempCookie.SetExpirationDate(atoi(tempString)); break; - + case 5: tempCookie.SetName(tempString); break; - + case 6: tempCookie.SetValue(tempString); break; } // switch } // for loop - + AddCookie(tempCookie); } - } - + } + return B_OK; } @@ -346,7 +344,7 @@ BNetworkCookieJar::GetUrlIterator(const BUrl& url) const copy.SetPath("/"); return BNetworkCookieJar::UrlIterator(this, copy); } - + return BNetworkCookieJar::UrlIterator(this, url); } @@ -357,10 +355,10 @@ BNetworkCookieJar::_DoFlatten() const fFlattened.Truncate(0); BNetworkCookie* cookiePtr; - for (Iterator it(GetIterator()); (cookiePtr = it.Next()); ) { - fFlattened << cookiePtr->Domain() << '\t' << "TRUE" << '\t' - << cookiePtr->Path() << '\t' - << (cookiePtr->Secure()?"TRUE":"FALSE") << '\t' + for (Iterator it = GetIterator(); (cookiePtr = it.Next()) != NULL;) { + fFlattened << cookiePtr->Domain() << '\t' << "TRUE" << '\t' + << cookiePtr->Path() << '\t' + << (cookiePtr->Secure()?"TRUE":"FALSE") << '\t' << (int32)cookiePtr->ExpirationDate() << '\t' << cookiePtr->Name() << '\t' << cookiePtr->Value() << '\n'; } @@ -395,7 +393,7 @@ BNetworkCookieJar::Iterator::Iterator(const BNetworkCookieJar* cookieJar) { fIterator = new(std::nothrow) PrivateIterator( fCookieJar->fCookieHashMap->fHashMap.GetIterator()); - + // Locate first cookie _FindNext(); } @@ -419,7 +417,7 @@ BNetworkCookieJar::Iterator::Next() { if (!fElement) return NULL; - + BNetworkCookie* result = fElement; _FindNext(); return result; @@ -431,18 +429,18 @@ BNetworkCookieJar::Iterator::NextDomain() { if (!fElement) return NULL; - + BNetworkCookie* result = fElement; - + if (!fIterator->fCookieMapIterator.HasNext()) { fElement = NULL; return NULL; } - + fList = *(fIterator->fCookieMapIterator.NextValue()); fIndex = 0; fElement = reinterpret_cast(fList->ItemAt(fIndex)); - + return result; } @@ -452,7 +450,7 @@ BNetworkCookieJar::Iterator::Remove() { if (!fLastElement) return NULL; - + BNetworkCookie* result = fLastElement; if (fIndex == 0) { @@ -466,7 +464,7 @@ BNetworkCookieJar::Iterator::Remove() fList->RemoveItem(fIndex-1); fIndex--; } - + fLastElement = NULL; return result; } @@ -490,18 +488,18 @@ void BNetworkCookieJar::Iterator::_FindNext() { fLastElement = fElement; - + fIndex++; if (fList && fIndex < fList->CountItems()) { fElement = reinterpret_cast(fList->ItemAt(fIndex)); return; } - + if (!fIterator->fCookieMapIterator.HasNext()) { fElement = NULL; return; } - + fLastList = fList; fList = *(fIterator->fCookieMapIterator.NextValue()); fIndex = 0; @@ -538,11 +536,11 @@ BNetworkCookieJar::UrlIterator::UrlIterator(const BNetworkCookieJar* cookieJar, if (domain[0] != '.') domain.Prepend("."); - + // Prepending another dot since _FindNext is going to // call _SupDomain() domain.Prepend("."); - + fIterator = new(std::nothrow) PrivateIterator( fCookieJar->fCookieHashMap->fHashMap.GetIterator()); fIterator->fKey.SetTo(domain, domain.Length()); @@ -569,7 +567,7 @@ BNetworkCookieJar::UrlIterator::Next() { if (!fElement) return NULL; - + BNetworkCookie* result = fElement; _FindNext(); return result; @@ -581,15 +579,15 @@ BNetworkCookieJar::UrlIterator::Remove() { if (!fLastElement) return NULL; - + BNetworkCookie* result = fLastElement; fLastList->RemoveItem(fLastIndex); if (fLastList->CountItems() == 0) { - HashString lastKey(fLastElement->Domain(), + HashString lastKey(fLastElement->Domain(), fLastElement->Domain().Length()); - + delete fCookieJar->fCookieHashMap->fHashMap.Remove(lastKey); } @@ -620,10 +618,10 @@ BNetworkCookieJar::UrlIterator::_SupDomain() { BString domain(fIterator->fKey.GetString()); int32 nextDot = domain.FindFirst('.', 1); - + if (nextDot == -1) return false; - + domain.Remove(0, nextDot); fIterator->fKey.SetTo(domain.String(), domain.Length()); return true; @@ -635,17 +633,17 @@ BNetworkCookieJar::UrlIterator::_FindNext() { fLastIndex = fIndex; fLastElement = fElement; - + if (_FindPath()) return; - + fLastList = fList; do { if (!_SupDomain()) { fElement = NULL; return; } - + _FindDomain(); } while (!_FindPath()); } @@ -655,10 +653,10 @@ void BNetworkCookieJar::UrlIterator::_FindDomain() { fList = fCookieJar->fCookieHashMap->fHashMap.Get(fIterator->fKey); - + if (fList == NULL) fElement = NULL; - + fIndex = -1; } @@ -669,15 +667,15 @@ BNetworkCookieJar::UrlIterator::_FindPath() fIndex++; if (fList && fIndex < fList->CountItems()) { do { - fElement + fElement = reinterpret_cast(fList->ItemAt(fIndex)); - - if (fElement->IsValidForPath(fUrl.Path())) + + if (fElement->IsValidForPath(fUrl.Path())) return true; - + fIndex++; } while (fList && fIndex < fList->CountItems()); } - + return false; }