NetworkCookieJar: don't leak a new cookie if it has expired

This commit is contained in:
Hamish Morrison 2013-01-26 19:23:34 +00:00
parent dcaec19c9a
commit 2e7b5f9e18
1 changed files with 93 additions and 95 deletions

View File

@ -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<BNetworkCookie*>(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<BNetworkCookie*>(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<BNetworkCookie*>(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<char*>(buffer), 0,
fFlattened.CopyInto(reinterpret_cast<char*>(buffer), 0,
fFlattened.Length());
reinterpret_cast<char*>(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<const char*>(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<BNetworkCookie*>(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<BNetworkCookie*>(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<BNetworkCookie*>(fList->ItemAt(fIndex));
if (fElement->IsValidForPath(fUrl.Path()))
if (fElement->IsValidForPath(fUrl.Path()))
return true;
fIndex++;
} while (fList && fIndex < fList->CountItems());
}
return false;
}