[BlackBerry] RefCounting ParsedCookie to avoid SegFaults
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 8 Mar 2013 01:31:02 +0000 (01:31 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 8 Mar 2013 01:31:02 +0000 (01:31 +0000)
https://bugs.webkit.org/show_bug.cgi?id=111761

Patch by Otto Derek Cheung <otcheung@rim.com> on 2013-03-07
Reviewed by Rob Buis.

Source/WebCore:

Making necessary changes to ref count the ParsedCookie object.

Tested using the opera cookie test suite and the BB Browser cookie test suite.
Tested using the browser, visiting popular sites such as facebook, reddit, google etc
to ensure cookie functionality isn't changed.

* loader/blackberry/CookieJarBlackBerry.cpp:
(WebCore::getRawCookies):
* platform/blackberry/CookieDatabaseBackingStore/CookieDatabaseBackingStore.cpp:
(WebCore::CookieDatabaseBackingStore::insert):
(WebCore::CookieDatabaseBackingStore::update):
(WebCore::CookieDatabaseBackingStore::remove):
(WebCore::CookieDatabaseBackingStore::getCookiesFromDatabase):
(WebCore::CookieDatabaseBackingStore::invokeGetCookiesWithLimit):
(WebCore::CookieDatabaseBackingStore::invokeSendChangesToDatabase):
(WebCore::CookieDatabaseBackingStore::addToChangeQueue):
* platform/blackberry/CookieDatabaseBackingStore/CookieDatabaseBackingStore.h:
(CookieDatabaseBackingStore):
* platform/blackberry/CookieManager.cpp:
(WebCore::cookieSorter):
(WebCore::CookieManager::setCookies):
(WebCore::CookieManager::getCookie):
(WebCore::CookieManager::generateHtmlFragmentForCookies):
(WebCore::CookieManager::getRawCookies):
(WebCore::CookieManager::checkAndTreatCookie):
(WebCore::CookieManager::addCookieToMap):
(WebCore::CookieManager::getBackingStoreCookies):
(WebCore::CookieManager::findOrCreateCookieMap):
(WebCore::CookieManager::removeCookieWithName):
(WebCore::CookieManager::cookieLimitCleanUp):
* platform/blackberry/CookieManager.h:
* platform/blackberry/CookieMap.cpp:
(WebCore::CookieMap::addOrReplaceCookie):
(WebCore::CookieMap::removeCookieAtIndex):
(WebCore::CookieMap::removeCookie):
(WebCore::CookieMap::getAllCookies):
(WebCore::CookieMap::removeOldestCookie):
(WebCore::CookieMap::deleteAllCookiesAndDomains):
(WebCore::CookieMap::getAllChildCookies):
* platform/blackberry/CookieMap.h:
(CookieMap):
* platform/blackberry/CookieParser.cpp:
(WebCore):
(WebCore::CookieParser::parse):
(WebCore::CookieParser::parseOneCookie):
* platform/blackberry/CookieParser.h:
(CookieParser):
* platform/blackberry/ParsedCookie.cpp:
* platform/blackberry/ParsedCookie.h:
(ParsedCookie):
(WebCore::ParsedCookie::create):

Source/WebKit/blackberry:

Making necessary changes to ref-count the ParsedCookie object.

* Api/WebCookieJar.cpp:
(BlackBerry::WebKit::WebCookieJar::cookies):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@145163 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
Source/WebCore/ChangeLog
Source/WebCore/loader/blackberry/CookieJarBlackBerry.cpp
Source/WebCore/platform/blackberry/CookieDatabaseBackingStore/CookieDatabaseBackingStore.cpp
Source/WebCore/platform/blackberry/CookieDatabaseBackingStore/CookieDatabaseBackingStore.h
Source/WebCore/platform/blackberry/CookieManager.cpp
Source/WebCore/platform/blackberry/CookieManager.h
Source/WebCore/platform/blackberry/CookieMap.cpp
Source/WebCore/platform/blackberry/CookieMap.h
Source/WebCore/platform/blackberry/CookieParser.cpp
Source/WebCore/platform/blackberry/CookieParser.h
Source/WebCore/platform/blackberry/ParsedCookie.cpp
Source/WebCore/platform/blackberry/ParsedCookie.h
Source/WebKit/blackberry/Api/WebCookieJar.cpp
Source/WebKit/blackberry/ChangeLog

index e8a4e54..531b824 100644 (file)
@@ -1,3 +1,62 @@
+2013-03-07  Otto Derek Cheung  <otcheung@rim.com>
+
+        [BlackBerry] RefCounting ParsedCookie to avoid SegFaults
+        https://bugs.webkit.org/show_bug.cgi?id=111761
+
+        Reviewed by Rob Buis.
+
+        Making necessary changes to ref count the ParsedCookie object.
+
+        Tested using the opera cookie test suite and the BB Browser cookie test suite.
+        Tested using the browser, visiting popular sites such as facebook, reddit, google etc
+        to ensure cookie functionality isn't changed.
+
+        * loader/blackberry/CookieJarBlackBerry.cpp:
+        (WebCore::getRawCookies):
+        * platform/blackberry/CookieDatabaseBackingStore/CookieDatabaseBackingStore.cpp:
+        (WebCore::CookieDatabaseBackingStore::insert):
+        (WebCore::CookieDatabaseBackingStore::update):
+        (WebCore::CookieDatabaseBackingStore::remove):
+        (WebCore::CookieDatabaseBackingStore::getCookiesFromDatabase):
+        (WebCore::CookieDatabaseBackingStore::invokeGetCookiesWithLimit):
+        (WebCore::CookieDatabaseBackingStore::invokeSendChangesToDatabase):
+        (WebCore::CookieDatabaseBackingStore::addToChangeQueue):
+        * platform/blackberry/CookieDatabaseBackingStore/CookieDatabaseBackingStore.h:
+        (CookieDatabaseBackingStore):
+        * platform/blackberry/CookieManager.cpp:
+        (WebCore::cookieSorter):
+        (WebCore::CookieManager::setCookies):
+        (WebCore::CookieManager::getCookie):
+        (WebCore::CookieManager::generateHtmlFragmentForCookies):
+        (WebCore::CookieManager::getRawCookies):
+        (WebCore::CookieManager::checkAndTreatCookie):
+        (WebCore::CookieManager::addCookieToMap):
+        (WebCore::CookieManager::getBackingStoreCookies):
+        (WebCore::CookieManager::findOrCreateCookieMap):
+        (WebCore::CookieManager::removeCookieWithName):
+        (WebCore::CookieManager::cookieLimitCleanUp):
+        * platform/blackberry/CookieManager.h:
+        * platform/blackberry/CookieMap.cpp:
+        (WebCore::CookieMap::addOrReplaceCookie):
+        (WebCore::CookieMap::removeCookieAtIndex):
+        (WebCore::CookieMap::removeCookie):
+        (WebCore::CookieMap::getAllCookies):
+        (WebCore::CookieMap::removeOldestCookie):
+        (WebCore::CookieMap::deleteAllCookiesAndDomains):
+        (WebCore::CookieMap::getAllChildCookies):
+        * platform/blackberry/CookieMap.h:
+        (CookieMap):
+        * platform/blackberry/CookieParser.cpp:
+        (WebCore):
+        (WebCore::CookieParser::parse):
+        (WebCore::CookieParser::parseOneCookie):
+        * platform/blackberry/CookieParser.h:
+        (CookieParser):
+        * platform/blackberry/ParsedCookie.cpp:
+        * platform/blackberry/ParsedCookie.h:
+        (ParsedCookie):
+        (WebCore::ParsedCookie::create):
+
 2013-03-07  Aaron Colwell  <acolwell@chromium.org>
 
         Heap-use-after-free in WebCore::HTMLMediaElement::~HTMLMediaElement
index 6fd6de2..e919a1c 100644 (file)
@@ -60,7 +60,7 @@ bool cookiesEnabled(const Document* document)
 bool getRawCookies(const Document* document, const KURL& url, Vector<Cookie>& rawCookies)
 {
     // Note: this method is called by inspector only. No need to check if cookie is enabled.
-    Vector<ParsedCookie*> result;
+    Vector<RefPtr<ParsedCookie> > result;
     cookieManager().getRawCookies(result, url, WithHttpOnlyCookies);
     for (size_t i = 0; i < result.size(); i++)
         result[i]->appendWebCoreCookie(rawCookies);
index 9076146..f5a5bb0 100644 (file)
@@ -197,19 +197,19 @@ void CookieDatabaseBackingStore::close()
         m_db.close();
 }
 
-void CookieDatabaseBackingStore::insert(const ParsedCookie* cookie)
+void CookieDatabaseBackingStore::insert(const PassRefPtr<ParsedCookie> cookie)
 {
     CookieLog("CookieBackingStore - adding inserting cookie %s to queue.", cookie->toString().utf8().data());
     addToChangeQueue(cookie, Insert);
 }
 
-void CookieDatabaseBackingStore::update(const ParsedCookie* cookie)
+void CookieDatabaseBackingStore::update(const PassRefPtr<ParsedCookie> cookie)
 {
     CookieLog("CookieBackingStore - adding updating cookie %s to queue.", cookie->toString().utf8().data());
     addToChangeQueue(cookie, Update);
 }
 
-void CookieDatabaseBackingStore::remove(const ParsedCookie* cookie)
+void CookieDatabaseBackingStore::remove(const PassRefPtr<ParsedCookie> cookie)
 {
     CookieLog("CookieBackingStore - adding deleting cookie %s to queue.", cookie->toString().utf8().data());
     addToChangeQueue(cookie, Delete);
@@ -252,18 +252,18 @@ void CookieDatabaseBackingStore::invokeRemoveAll()
     }
 }
 
-void CookieDatabaseBackingStore::getCookiesFromDatabase(Vector<ParsedCookie*>& stackOfCookies, unsigned int limit)
+void CookieDatabaseBackingStore::getCookiesFromDatabase(Vector<RefPtr<ParsedCookie> >& stackOfCookies, unsigned limit)
 {
     // It is not a huge performance hit to wait on the reply here because this is only done once during setup and when turning off private mode.
-    TypedReplyBuffer< Vector<ParsedCookie*>* > replyBuffer(0);
+    TypedReplyBuffer< Vector<RefPtr<ParsedCookie> >* > replyBuffer(0);
     dispatchMessage(createMethodCallMessageWithReturn(&CookieDatabaseBackingStore::invokeGetCookiesWithLimit, &replyBuffer, this, limit));
-    Vector<ParsedCookie*>* cookies = replyBuffer.pointer();
+    Vector<RefPtr<ParsedCookie> >* cookies = replyBuffer.pointer();
     if (cookies)
         stackOfCookies.swap(*cookies);
     delete cookies;
 }
 
-Vector<ParsedCookie*>* CookieDatabaseBackingStore::invokeGetCookiesWithLimit(unsigned int limit)
+Vector<RefPtr<ParsedCookie> >* CookieDatabaseBackingStore::invokeGetCookiesWithLimit(unsigned limit)
 {
     ASSERT(isCurrentThread());
 
@@ -290,7 +290,7 @@ Vector<ParsedCookie*>* CookieDatabaseBackingStore::invokeGetCookiesWithLimit(uns
         return 0;
     }
 
-    Vector<ParsedCookie*>* cookies = new Vector<ParsedCookie*>;
+    Vector<RefPtr<ParsedCookie> >* cookies = new Vector<RefPtr<ParsedCookie> >;
     while (selectStatement.step() == SQLResultRow) {
         // There is a row to fetch
 
@@ -305,7 +305,7 @@ Vector<ParsedCookie*>* CookieDatabaseBackingStore::invokeGetCookiesWithLimit(uns
         double creationTime = selectStatement.getColumnDouble(8);
         String protocol = selectStatement.getColumnText(9);
 
-        cookies->append(new ParsedCookie(name, value, domain, protocol, path, expiry, lastAccessed, creationTime, isSecure, isHttpOnly));
+        cookies->append(ParsedCookie::create(name, value, domain, protocol, path, expiry, lastAccessed, creationTime, isSecure, isHttpOnly));
     }
 
     return cookies;
@@ -389,7 +389,7 @@ void CookieDatabaseBackingStore::invokeSendChangesToDatabase()
     size_t sizeOfChange = changedCookies.size();
     for (size_t i = 0; i < sizeOfChange; i++) {
         SQLiteStatement* m_statement;
-        const ParsedCookie cookie = changedCookies[i].first;
+        const RefPtr<ParsedCookie> cookie = changedCookies[i].first;
         UpdateParameter action = changedCookies[i].second;
 
         if (action == Delete) {
@@ -397,8 +397,8 @@ void CookieDatabaseBackingStore::invokeSendChangesToDatabase()
             CookieLog("CookieBackingStore - deleting cookie %s.", cookie.toString().utf8().data());
 
             // Binds all the values
-            if (m_statement->bindText(1, cookie.name()) || m_statement->bindText(2, cookie.domain())
-                || m_statement->bindText(3, cookie.path()) || m_statement->bindText(4, cookie.protocol())) {
+            if (m_statement->bindText(1, cookie->name()) || m_statement->bindText(2, cookie->domain())
+                || m_statement->bindText(3, cookie->path()) || m_statement->bindText(4, cookie->protocol())) {
                 LOG_ERROR("Cannot bind cookie data to delete");
                 LOG_ERROR("SQLite Error Message: %s", m_db.lastErrorMsg());
                 ASSERT_NOT_REACHED();
@@ -406,19 +406,19 @@ void CookieDatabaseBackingStore::invokeSendChangesToDatabase()
             }
         } else {
             if (action == Update) {
-                CookieLog("CookieBackingStore - updating cookie %s.", cookie.toString().utf8().data());
+                CookieLog("CookieBackingStore - updating cookie %s.", cookie->toString().utf8().data());
                 m_statement = m_updateStatement;
             } else {
-                CookieLog("CookieBackingStore - inserting cookie %s.", cookie.toString().utf8().data());
+                CookieLog("CookieBackingStore - inserting cookie %s.", cookie->toString().utf8().data());
                 m_statement = m_insertStatement;
             }
 
             // Binds all the values
-            if (m_statement->bindText(1, cookie.name()) || m_statement->bindText(2, cookie.value())
-                || m_statement->bindText(3, cookie.domain()) || m_statement->bindText(4, cookie.path())
-                || m_statement->bindDouble(5, cookie.expiry()) || m_statement->bindDouble(6, cookie.lastAccessed())
-                || m_statement->bindInt64(7, cookie.isSecure()) || m_statement->bindInt64(8, cookie.isHttpOnly())
-                || m_statement->bindDouble(9, cookie.creationTime()) || m_statement->bindText(10, cookie.protocol())) {
+            if (m_statement->bindText(1, cookie->name()) || m_statement->bindText(2, cookie->value())
+                || m_statement->bindText(3, cookie->domain()) || m_statement->bindText(4, cookie->path())
+                || m_statement->bindDouble(5, cookie->expiry()) || m_statement->bindDouble(6, cookie->lastAccessed())
+                || m_statement->bindInt64(7, cookie->isSecure()) || m_statement->bindInt64(8, cookie->isHttpOnly())
+                || m_statement->bindDouble(9, cookie->creationTime()) || m_statement->bindText(10, cookie->protocol())) {
                 LOG_ERROR("Cannot bind cookie data to save");
                 LOG_ERROR("SQLite Error Message: %s", m_db.lastErrorMsg());
                 ASSERT_NOT_REACHED();
@@ -439,11 +439,10 @@ void CookieDatabaseBackingStore::invokeSendChangesToDatabase()
     CookieLog("CookieBackingStore - transaction complete");
 }
 
-void CookieDatabaseBackingStore::addToChangeQueue(const ParsedCookie* changedCookie, UpdateParameter actionParam)
+void CookieDatabaseBackingStore::addToChangeQueue(const PassRefPtr<ParsedCookie> changedCookie, UpdateParameter actionParam)
 {
     ASSERT(!changedCookie->isSession());
-    ParsedCookie cookieCopy(changedCookie);
-    CookieAction action(cookieCopy, actionParam);
+    CookieAction action(changedCookie, actionParam);
     {
         MutexLocker lock(m_mutex);
         m_changedCookies.append(action);
index 8834f4e..75c0b77 100644 (file)
@@ -50,14 +50,14 @@ public:
 
     void open(const String& cookieJar);
 
-    void insert(const ParsedCookie*);
-    void update(const ParsedCookie*);
-    void remove(const ParsedCookie*);
+    void insert(const PassRefPtr<ParsedCookie>);
+    void update(const PassRefPtr<ParsedCookie>);
+    void remove(const PassRefPtr<ParsedCookie>);
 
     void removeAll();
 
     // If a limit is not set, the method will return all cookies in the database
-    void getCookiesFromDatabase(Vector<ParsedCookie*>& stackOfCookies, unsigned int limit = 0);
+    void getCookiesFromDatabase(Vector<RefPtr<ParsedCookie> >& stackOfCookies, unsigned limit = 0);
 
     void openAndLoadDatabaseSynchronously(const String& cookieJar);
     void sendChangesToDatabaseSynchronously();
@@ -81,18 +81,18 @@ private:
     CookieDatabaseBackingStore();
     ~CookieDatabaseBackingStore();
 
-    void addToChangeQueue(const ParsedCookie* changedCookie, UpdateParameter actionParam);
+    void addToChangeQueue(const PassRefPtr<ParsedCookie> changedCookie, UpdateParameter actionParam);
     void sendChangesToDatabase(int interval);
     void sendChangesToDatabaseTimerFired();
 
     void invokeOpen(const String& cookieJar);
     void invokeRemoveAll();
-    Vector<ParsedCookie*>* invokeGetCookiesWithLimit(unsigned int limit);
+    Vector<RefPtr<ParsedCookie> >* invokeGetCookiesWithLimit(unsigned limit);
     void invokeSendChangesToDatabase();
 
     void close();
 
-    typedef pair<const ParsedCookie, UpdateParameter> CookieAction;
+    typedef pair<const PassRefPtr<ParsedCookie>, UpdateParameter> CookieAction;
     Vector<CookieAction> m_changedCookies;
     Mutex m_mutex;
 
index 0bbf277..b246d28 100644 (file)
@@ -110,7 +110,7 @@ CookieManager::~CookieManager()
 }
 
 // Sorting logic is based on Cookie Spec RFC6265, section 5.4.2
-static bool cookieSorter(ParsedCookie* a, ParsedCookie* b)
+static bool cookieSorter(PassRefPtr<ParsedCookie> a, PassRefPtr<ParsedCookie> b)
 {
     if (a->path().length() == b->path().length())
         return a->creationTime() < b->creationTime();
@@ -132,7 +132,7 @@ void CookieManager::setCookies(const KURL& url, const String& value, CookieFilte
 
     CookieLog("CookieManager - Setting cookies");
     CookieParser parser(url);
-    Vector<ParsedCookie*> cookies = parser.parse(value);
+    Vector<RefPtr<ParsedCookie> > cookies = parser.parse(value);
 
     for (size_t i = 0; i < cookies.size(); ++i) {
         BackingStoreRemovalPolicy treatment = m_privateMode ? DoNotRemoveFromBackingStore : RemoveFromBackingStore;
@@ -150,7 +150,7 @@ void CookieManager::setCookies(const KURL& url, const Vector<String>& cookies, C
     CookieParser parser(url);
     for (size_t i = 0; i < cookies.size(); ++i) {
         BackingStoreRemovalPolicy treatment = m_privateMode ? DoNotRemoveFromBackingStore : RemoveFromBackingStore;
-        if (ParsedCookie* parsedCookie = parser.parseOneCookie(cookies[i]))
+        if (RefPtr<ParsedCookie> parsedCookie = parser.parseOneCookie(cookies[i]))
             checkAndTreatCookie(parsedCookie, treatment, filter);
     }
 }
@@ -161,7 +161,7 @@ String CookieManager::getCookie(const KURL& url, CookieFilter filter) const
     if (!m_syncedWithDatabase && !m_privateMode)
         m_cookieBackingStore->openAndLoadDatabaseSynchronously(cookieJar());
 
-    Vector<ParsedCookie*> rawCookies;
+    Vector<RefPtr<ParsedCookie> > rawCookies;
     rawCookies.reserveInitialCapacity(s_maxCookieCountPerHost);
 
     // Retrieve cookies related to this url
@@ -192,12 +192,12 @@ String CookieManager::generateHtmlFragmentForCookies()
 
     CookieLog("CookieManager - generateHtmlFragmentForCookies\n");
 
-    Vector<ParsedCookie*> cookieCandidates;
+    Vector<RefPtr<ParsedCookie> > cookieCandidates;
     for (HashMap<String, CookieMap*>::iterator it = m_managerMap.begin(); it != m_managerMap.end(); ++it)
         it->value->getAllChildCookies(&cookieCandidates);
 
     String result;
-    ParsedCookie* cookie = 0;
+    RefPtr<ParsedCookie> cookie = 0;
     result.append(String("<table style=\"word-wrap:break-word\" cellSpacing=\"0\" cellPadding=\"0\" border=\"1\"><tr><th>Domain</th><th>Path</th><th>Protocol</th><th>Name</th><th>Value</th><th>Secure</th><th>HttpOnly</th><th>Session</th></tr>"));
     for (size_t i = 0; i < cookieCandidates.size(); ++i) {
         cookie = cookieCandidates[i];
@@ -223,7 +223,7 @@ String CookieManager::generateHtmlFragmentForCookies()
     return result;
 }
 
-void CookieManager::getRawCookies(Vector<ParsedCookie*> &stackOfCookies, const KURL& requestURL, CookieFilter filter) const
+void CookieManager::getRawCookies(Vector<RefPtr<ParsedCookie> > &stackOfCookies, const KURL& requestURL, CookieFilter filter) const
 {
     // Force a sync load of the database
     if (!m_syncedWithDatabase && !m_privateMode)
@@ -235,7 +235,7 @@ void CookieManager::getRawCookies(Vector<ParsedCookie*> &stackOfCookies, const K
     const bool specialCaseForWebWorks = invalidScheme && m_shouldDumpAllCookies;
     const bool isConnectionSecure = requestURL.protocolIs("https") || requestURL.protocolIs("wss") || specialCaseForWebWorks;
 
-    Vector<ParsedCookie*> cookieCandidates;
+    Vector<RefPtr<ParsedCookie> > cookieCandidates;
     Vector<CookieMap*> protocolsToSearch;
 
     // Special Case: If a server sets a "secure" cookie over a non-secure channel and tries to access the cookie
@@ -316,7 +316,7 @@ void CookieManager::getRawCookies(Vector<ParsedCookie*> &stackOfCookies, const K
     CookieLog("CookieManager - there are %d cookies in candidate\n", cookieCandidates.size());
 
     for (size_t i = 0; i < cookieCandidates.size(); ++i) {
-        ParsedCookie* cookie = cookieCandidates[i];
+        RefPtr<ParsedCookie> cookie = cookieCandidates[i];
 
         // According to the path-matches rules in RFC6265, section 5.1.4,
         // we should add a '/' at the end of cookie-path for comparison if the cookie-path is not end with '/'.
@@ -355,17 +355,16 @@ void CookieManager::setCookieJar(const char* fileName)
     m_cookieBackingStore->open(m_cookieJarFileName);
 }
 
-void CookieManager::checkAndTreatCookie(ParsedCookie* candidateCookie, BackingStoreRemovalPolicy postToBackingStore, CookieFilter filter)
+void CookieManager::checkAndTreatCookie(PassRefPtr<ParsedCookie> prpCandidateCookie, BackingStoreRemovalPolicy postToBackingStore, CookieFilter filter)
 {
+    RefPtr<ParsedCookie> candidateCookie = prpCandidateCookie;
     CookieLog("CookieManager - checkAndTreatCookie - processing url with domain - %s & protocol %s\n", candidateCookie->domain().utf8().data(), candidateCookie->protocol().utf8().data());
 
     // Delete invalid cookies:
     // 1) A cookie which is not from http shouldn't have a httpOnly property.
     // 2) Cookies coming from schemes that we do not support and the special flag isn't on
-    if ((filter == NoHttpOnlyCookie && candidateCookie->isHttpOnly()) || (shouldIgnoreScheme(candidateCookie->protocol()) && !m_shouldDumpAllCookies)) {
-        delete candidateCookie;
+    if ((filter == NoHttpOnlyCookie && candidateCookie->isHttpOnly()) || (shouldIgnoreScheme(candidateCookie->protocol()) && !m_shouldDumpAllCookies))
         return;
-    }
 
     const bool ignoreDomain = (candidateCookie->protocol() == "file" || candidateCookie->protocol() == "local");
 
@@ -399,7 +398,7 @@ void CookieManager::checkAndTreatCookie(ParsedCookie* candidateCookie, BackingSt
     // If protocol support domain, we have to traverse the domain tree to find the right
     // cookieMap to handle with
     if (!ignoreDomain)
-        curMap = findOrCreateCookieMap(curMap, *candidateCookie);
+        curMap = findOrCreateCookieMap(curMap, candidateCookie);
 
     // Now that we have the proper map for this cookie, we can modify it
     // If cookie does not exist and has expired, delete it
@@ -413,32 +412,27 @@ void CookieManager::checkAndTreatCookie(ParsedCookie* candidateCookie, BackingSt
             m_cookieBackingStore->remove(candidateCookie);
         else if (curMap) {
             // RemoveCookie will return 0 if the cookie doesn't exist.
-            ParsedCookie* expired = curMap->removeCookie(candidateCookie, filter);
+            RefPtr<ParsedCookie> expired = curMap->removeCookie(candidateCookie, filter);
             // Cookie is useless, Remove the cookie from the backingstore if it exists.
             // Backup check for BackingStoreCookieEntry incase someone incorrectly uses this enum.
             if (expired && postToBackingStore != BackingStoreCookieEntry && !expired->isSession()) {
                 CookieLog("CookieManager - expired cookie is nonsession, deleting from db");
                 m_cookieBackingStore->remove(expired);
             }
-            delete expired;
-
-        } else
-            delete candidateCookie;
+        }
     } else {
         ASSERT(curMap);
         addCookieToMap(curMap, candidateCookie, postToBackingStore, filter);
     }
 }
 
-void CookieManager::addCookieToMap(CookieMap* targetMap, ParsedCookie* candidateCookie, BackingStoreRemovalPolicy postToBackingStore, CookieFilter filter)
+void CookieManager::addCookieToMap(CookieMap* targetMap, PassRefPtr<ParsedCookie> prpCandidateCookie, BackingStoreRemovalPolicy postToBackingStore, CookieFilter filter)
 {
-    ParsedCookie* replacedCookie = 0;
-
-    if (!targetMap->addOrReplaceCookie(candidateCookie, &replacedCookie, filter)) {
+    RefPtr<ParsedCookie> replacedCookie = 0;
+    RefPtr<ParsedCookie> candidateCookie = prpCandidateCookie;
 
+    if (!targetMap->addOrReplaceCookie(candidateCookie, replacedCookie, filter)) {
         CookieLog("CookieManager - rejecting new cookie - %s.\n", candidateCookie->toString().utf8().data());
-
-        delete candidateCookie;
         return;
     }
 
@@ -467,13 +461,12 @@ void CookieManager::addCookieToMap(CookieMap* targetMap, ParsedCookie* candidate
                 m_cookieBackingStore->insert(candidateCookie);
             }
         }
-        delete replacedCookie;
         return;
     }
 
     CookieLog("CookieManager - adding new cookie - %s.\n", candidateCookie->toString().utf8().data());
 
-    ParsedCookie* oldestCookie = 0;
+    RefPtr<ParsedCookie> oldestCookie = 0;
     // Check if we have not reached the per cookie domain limit.
     // If that is not true, we check if the global limit has been reached if backingstore mode is on
     // Two points:
@@ -502,8 +495,6 @@ void CookieManager::addCookieToMap(CookieMap* targetMap, ParsedCookie* candidate
         if (!candidateCookie->isSession())
             m_cookieBackingStore->insert(candidateCookie);
     }
-    if (oldestCookie)
-        delete oldestCookie;
 }
 
 void CookieManager::getBackingStoreCookies()
@@ -516,11 +507,11 @@ void CookieManager::getBackingStoreCookies()
     if (m_count)
         removeAllCookies(DoNotRemoveFromBackingStore);
 
-    Vector<ParsedCookie*> cookies;
+    Vector<RefPtr<ParsedCookie> > cookies;
     m_cookieBackingStore->getCookiesFromDatabase(cookies);
     CookieLog("CookieManager - Backingstore has %d cookies, loading them in memory now", cookies.size());
     for (size_t i = 0; i < cookies.size(); ++i) {
-        ParsedCookie* newCookie = cookies[i];
+        RefPtr<ParsedCookie> newCookie = cookies[i];
 
         // The IP flag is not persisted in the database.
         if (BlackBerry::Platform::isIPAddress(newCookie->domain().utf8().data()))
@@ -552,16 +543,16 @@ void CookieManager::setPrivateMode(bool privateMode)
         getBackingStoreCookies();
 }
 
-CookieMap* CookieManager::findOrCreateCookieMap(CookieMap* protocolMap, const ParsedCookie& candidateCookie)
+CookieMap* CookieManager::findOrCreateCookieMap(CookieMap* protocolMap, const PassRefPtr<ParsedCookie> candidateCookie)
 {
     // Explode the domain with the '.' delimiter
     Vector<String> delimitedHost;
 
     // If the domain is an IP address, don't split it.
-    if (candidateCookie.domainIsIPAddress())
-        delimitedHost.append(candidateCookie.domain());
+    if (candidateCookie->domainIsIPAddress())
+        delimitedHost.append(candidateCookie->domain());
     else
-        candidateCookie.domain().split(".", delimitedHost);
+        candidateCookie->domain().split(".", delimitedHost);
 
     CookieMap* curMap = protocolMap;
     size_t hostSize = delimitedHost.size();
@@ -576,7 +567,7 @@ CookieMap* CookieManager::findOrCreateCookieMap(CookieMap* protocolMap, const Pa
         CookieMap* nextMap = curMap->getSubdomainMap(delimitedHost[i]);
         if (!nextMap) {
             CookieLog("CookieManager - cannot find map\n");
-            if (candidateCookie.hasExpired())
+            if (candidateCookie->hasExpired())
                 return 0;
             CookieLog("CookieManager - creating %s in currentmap %s\n", delimitedHost[i].utf8().data(), curMap->getName().utf8().data());
             nextMap = new CookieMap(delimitedHost[i]);
@@ -602,11 +593,11 @@ void CookieManager::removeCookieWithName(const KURL& url, const String& cookieNa
 
     // We get all cookies from all domains that domain matches the request domain
     // and delete any cookies with the specified name that path matches the request path
-    Vector<ParsedCookie*> results;
+    Vector<RefPtr<ParsedCookie> > results;
     getRawCookies(results, url, WithHttpOnlyCookies);
     // Delete the cookies that path matches the request path
     for (size_t i = 0; i < results.size(); i++) {
-        ParsedCookie* cookie = results[i];
+        RefPtr<ParsedCookie> cookie = results[i];
         if (!equalIgnoringCase(cookie->name(), cookieName))
             continue;
         if (url.path().startsWith(cookie->path(), false)) {
@@ -640,7 +631,7 @@ void CookieManager::cookieLimitCleanUp(Timer<CookieManager>* timer)
     CookieLimitLog("CookieManager - Excess: %d  Amount to Delete: %d", numberOfCookiesOverLimit, amountToDelete);
 
     // Call the database to delete 'amountToDelete' of cookies
-    Vector<ParsedCookie*> cookiesToDelete;
+    Vector<RefPtr<ParsedCookie> > cookiesToDelete;
     cookiesToDelete.reserveInitialCapacity(amountToDelete);
 
     CookieLimitLog("CookieManager - Calling database to clean up");
@@ -649,7 +640,7 @@ void CookieManager::cookieLimitCleanUp(Timer<CookieManager>* timer)
     // Cookies are ordered in ASC order by lastAccessed
     for (size_t i = 0; i < amountToDelete; ++i) {
         // Expire them and call checkandtreat to delete them from memory and database
-        ParsedCookie* newCookie = cookiesToDelete[i];
+        RefPtr<ParsedCookie> newCookie = cookiesToDelete[i];
         CookieLimitLog("CookieManager - Expire cookie: %s and delete", newCookie->toString().utf8().data());
         newCookie->forceExpire();
         checkAndTreatCookie(newCookie, RemoveFromBackingStore);
index 3d101d9..0d690fc 100644 (file)
@@ -99,7 +99,7 @@ public:
     String getCookie(const KURL& requestURL, CookieFilter) const;
 
     // Returns all cookies that are associated with the specified URL as raw cookies.
-    void getRawCookies(Vector<ParsedCookie*>& stackOfCookies, const KURL& requestURL, CookieFilter = WithHttpOnlyCookies) const;
+    void getRawCookies(Vector<RefPtr<ParsedCookie> >& stackOfCookies, const KURL& requestURL, CookieFilter = WithHttpOnlyCookies) const;
 
 private:
     friend CookieManager& cookieManager();
@@ -108,11 +108,11 @@ private:
     CookieManager();
     virtual ~CookieManager();
 
-    void checkAndTreatCookie(ParsedCookie*, BackingStoreRemovalPolicy, CookieFilter = WithHttpOnlyCookies);
+    void checkAndTreatCookie(PassRefPtr<ParsedCookie> prpCandidateCookie, BackingStoreRemovalPolicy, CookieFilter = WithHttpOnlyCookies);
 
-    void addCookieToMap(CookieMap* targetMap, ParsedCookie* candidateCookie, BackingStoreRemovalPolicy postToBackingStore, CookieFilter = WithHttpOnlyCookies);
+    void addCookieToMap(CookieMap* targetMap, PassRefPtr<ParsedCookie> prpCandidateCookie, BackingStoreRemovalPolicy postToBackingStore, CookieFilter = WithHttpOnlyCookies);
 
-    CookieMap* findOrCreateCookieMap(CookieMap* protocolMap, const ParsedCookie& candidateCookie);
+    CookieMap* findOrCreateCookieMap(CookieMap* protocolMap, const PassRefPtr<ParsedCookie> candidateCookie);
 
     void initiateCookieLimitCleanUp();
     void cookieLimitCleanUp(Timer<CookieManager>*);
index af485b5..e45e3b8 100644 (file)
@@ -54,8 +54,9 @@ CookieMap::~CookieMap()
     deleteAllCookiesAndDomains();
 }
 
-bool CookieMap::addOrReplaceCookie(ParsedCookie* candidateCookie, ParsedCookie** replacedCookie, CookieFilter filter)
+bool CookieMap::addOrReplaceCookie(PassRefPtr<ParsedCookie> prpCandidateCookie, RefPtr<ParsedCookie>& replacedCookie, CookieFilter filter)
 {
+    RefPtr<ParsedCookie> candidateCookie = prpCandidateCookie;
     CookieLog("CookieMap - Attempting to add cookie - %s", cookie->name().utf8().data());
 
     size_t cookieCount = m_cookieVector.size();
@@ -65,9 +66,9 @@ bool CookieMap::addOrReplaceCookie(ParsedCookie* candidateCookie, ParsedCookie**
             if (filter == NoHttpOnlyCookie && m_cookieVector[i]->isHttpOnly())
                 return false;
 
-            *replacedCookie = m_cookieVector[i];
+            replacedCookie = m_cookieVector[i];
             m_cookieVector[i] = candidateCookie;
-            if (*replacedCookie == m_oldestCookie)
+            if (replacedCookie == m_oldestCookie)
                 updateOldestCookie();
             return true;
         }
@@ -81,10 +82,10 @@ bool CookieMap::addOrReplaceCookie(ParsedCookie* candidateCookie, ParsedCookie**
     return true;
 }
 
-ParsedCookie* CookieMap::removeCookieAtIndex(int position, const ParsedCookie* cookie)
+PassRefPtr<ParsedCookie> CookieMap::removeCookieAtIndex(int position, const PassRefPtr<ParsedCookie> cookie)
 {
     ASSERT(0 <= position && static_cast<unsigned>(position) < m_cookieVector.size());
-    ParsedCookie* prevCookie = m_cookieVector[position];
+    RefPtr<ParsedCookie> prevCookie = m_cookieVector[position];
     m_cookieVector.remove(position);
 
     if (prevCookie == m_oldestCookie)
@@ -94,7 +95,6 @@ ParsedCookie* CookieMap::removeCookieAtIndex(int position, const ParsedCookie* c
         // to the cookie in memory too.
         if (cookie->isForceExpired())
             prevCookie->forceExpire();
-        delete cookie;
     }
 
     if (!prevCookie->isSession())
@@ -102,7 +102,7 @@ ParsedCookie* CookieMap::removeCookieAtIndex(int position, const ParsedCookie* c
     return prevCookie;
 }
 
-ParsedCookie* CookieMap::removeCookie(const ParsedCookie* cookie, CookieFilter filter)
+PassRefPtr<ParsedCookie> CookieMap::removeCookie(const PassRefPtr<ParsedCookie> cookie, CookieFilter filter)
 {
     size_t cookieCount = m_cookieVector.size();
     for (size_t position = 0; position < cookieCount; ++position) {
@@ -130,7 +130,7 @@ void CookieMap::addSubdomainMap(const String& subdomain, CookieMap* newDomain)
     m_subdomains.add(subdomain, newDomain);
 }
 
-void CookieMap::getAllCookies(Vector<ParsedCookie*>* stackOfCookies)
+void CookieMap::getAllCookies(Vector<RefPtr<ParsedCookie> >* stackOfCookies)
 {
     CookieLog("CookieMap - Attempting to copy Map:%s cookies with %d cookies into vectors", m_name.utf8().data(), m_cookieVector.size());
 
@@ -138,12 +138,11 @@ void CookieMap::getAllCookies(Vector<ParsedCookie*>* stackOfCookies)
 
     size_t position = 0;
     while (position < m_cookieVector.size()) {
-        ParsedCookie* newCookie = m_cookieVector[position];
+        RefPtr<ParsedCookie> newCookie = m_cookieVector[position];
         if (newCookie->hasExpired()) {
             // Notice that we don't delete from backingstore. These expired cookies will be
             // deleted when manager loads the backingstore again.
-            ParsedCookie* expired = removeCookieAtIndex(position, newCookie);
-            delete expired;
+            removeCookieAtIndex(position, newCookie);
         } else {
             stackOfCookies->append(newCookie);
             position++;
@@ -153,10 +152,10 @@ void CookieMap::getAllCookies(Vector<ParsedCookie*>* stackOfCookies)
     CookieLog("CookieMap - stack of cookies now have %d cookies in it", (*stackOfCookies).size());
 }
 
-ParsedCookie* CookieMap::removeOldestCookie()
+PassRefPtr<ParsedCookie> CookieMap::removeOldestCookie()
 {
     // FIXME: Make sure it finds the GLOBAL oldest cookie, not the first oldestcookie it finds.
-    ParsedCookie* oldestCookie = m_oldestCookie;
+    RefPtr<ParsedCookie> oldestCookie = m_oldestCookie;
 
     // If this map has an oldestCookie, remove it. If not, do a DFS to search for a child that does
     if (!oldestCookie) {
@@ -203,13 +202,12 @@ void CookieMap::deleteAllCookiesAndDomains()
 {
     deleteAllValues(m_subdomains);
     m_subdomains.clear();
-    deleteAllValues(m_cookieVector);
     m_cookieVector.clear();
 
     m_oldestCookie = 0;
 }
 
-void CookieMap::getAllChildCookies(Vector<ParsedCookie*>* stackOfCookies)
+void CookieMap::getAllChildCookies(Vector<RefPtr<ParsedCookie> >* stackOfCookies)
 {
     CookieLog("CookieMap - getAllChildCookies in Map - %s", getName().utf8().data());
     getAllCookies(stackOfCookies);
index 671ac29..98ed001 100644 (file)
@@ -60,32 +60,32 @@ public:
     const String& getName() const { return m_name; }
 
     // Return false if the candidateCookie is rejected.
-    bool addOrReplaceCookie(ParsedCookie* candidateCookie, ParsedCookie** replacedCookie, CookieFilter = WithHttpOnlyCookies);
+    bool addOrReplaceCookie(PassRefPtr<ParsedCookie> prpCandidateCookie, RefPtr<ParsedCookie>& replacedCookie, CookieFilter = WithHttpOnlyCookies);
 
     // Need to return the reference to the removed cookie so manager can deal with it (garbage collect).
-    ParsedCookie* removeCookie(const ParsedCookie*, CookieFilter = WithHttpOnlyCookies);
+    PassRefPtr<ParsedCookie> removeCookie(const PassRefPtr<ParsedCookie>, CookieFilter = WithHttpOnlyCookies);
 
     // Returns a map with that given subdomain.
     CookieMap* getSubdomainMap(const String&);
     void addSubdomainMap(const String&, CookieMap*);
     void deleteAllCookiesAndDomains();
 
-    void getAllCookies(Vector<ParsedCookie*>*);
-    void getAllChildCookies(Vector<ParsedCookie*>* stackOfCookies);
-    ParsedCookie* removeOldestCookie();
+    void getAllCookies(Vector<RefPtr<ParsedCookie> >*);
+    void getAllChildCookies(Vector<RefPtr<ParsedCookie> >* stackOfCookies);
+    PassRefPtr<ParsedCookie> removeOldestCookie();
 
 private:
     void updateOldestCookie();
-    ParsedCookie* removeCookieAtIndex(int position, const ParsedCookie*);
+    PassRefPtr<ParsedCookie> removeCookieAtIndex(int position, const PassRefPtr<ParsedCookie>);
 
-    Vector<ParsedCookie*> m_cookieVector;
+    Vector<RefPtr<ParsedCookie> > m_cookieVector;
     // The key is a subsection of the domain.
     // ex: if inserting accounts.google.com & this cookiemap is "com", this subdomain map will contain "google"
     // the "google" cookiemap will contain "accounts" in its subdomain map.
     HashMap<String, CookieMap*> m_subdomains;
 
     // Store the oldest cookie to speed up LRU checks.
-    ParsedCookie* m_oldestCookie;
+    RefPtr<ParsedCookie> m_oldestCookie;
     const String m_name;
 
     // FIXME : should have a m_shouldUpdate flag to update the network layer only when the map has changed.
index 79a3c30..b483778 100644 (file)
 
 namespace WebCore {
 
-#define LOG_AND_DELETE(format, ...) \
+#define LOG_ERROR_AND_RETURN(format, ...) \
     { \
         LOG_ERROR(format, ## __VA_ARGS__); \
-        delete res; \
         return 0; \
     }
 
@@ -69,11 +68,11 @@ CookieParser::~CookieParser()
 {
 }
 
-Vector<ParsedCookie*> CookieParser::parse(const String& cookies)
+Vector<RefPtr<ParsedCookie> > CookieParser::parse(const String& cookies)
 {
     unsigned cookieStart, cookieEnd = 0;
     double curTime = currentTime();
-    Vector<ParsedCookie*, 4> parsedCookies;
+    Vector<RefPtr<ParsedCookie>, 4> parsedCookies;
 
     unsigned cookiesLength = cookies.length();
     if (!cookiesLength) // Code below doesn't handle this case
@@ -96,26 +95,26 @@ Vector<ParsedCookie*> CookieParser::parse(const String& cookies)
         if (cookieEnd < cookiesLength && isCookieHeaderSeparator(cookies[cookieEnd]))
             ++cookieEnd;
 
-        ParsedCookie* cookie = parseOneCookie(cookies, cookieStart, cookieEnd - 1, curTime);
+        RefPtr<ParsedCookie> cookie = parseOneCookie(cookies, cookieStart, cookieEnd - 1, curTime);
         if (cookie)
             parsedCookies.append(cookie);
     }
     return parsedCookies;
 }
 
-ParsedCookie* CookieParser::parseOneCookie(const String& cookie)
+PassRefPtr<ParsedCookie> CookieParser::parseOneCookie(const String& cookie)
 {
     return parseOneCookie(cookie, 0, cookie.length() - 1, currentTime());
 }
 
 // The cookie String passed into this method will only contian the name value pairs as well as other related cookie
 // attributes such as max-age and domain. Set-Cookie should never be part of this string.
-ParsedCookie* CookieParser::parseOneCookie(const String& cookie, unsigned start, unsigned end, double curTime)
+PassRefPtr<ParsedCookie> CookieParser::parseOneCookie(const String& cookie, unsigned start, unsigned end, double curTime)
 {
-    ParsedCookie* res = new ParsedCookie(curTime);
+    RefPtr<ParsedCookie> res = ParsedCookie::create(curTime);
 
     if (!res)
-        LOG_AND_DELETE("Out of memory");
+        LOG_ERROR_AND_RETURN("Out of memory");
 
     res->setProtocol(m_defaultCookieURL.protocol());
 
@@ -160,7 +159,7 @@ ParsedCookie* CookieParser::parseOneCookie(const String& cookie, unsigned start,
             tokenStart++;
 
         if (nameEnd + 1 <= tokenStart)
-            LOG_AND_DELETE("Empty name. Rejecting the cookie");
+            LOG_ERROR_AND_RETURN("Empty name. Rejecting the cookie");
 
         String name = cookie.substring(tokenStart, nameEnd + 1 - start);
         res->setName(name);
@@ -189,10 +188,9 @@ ParsedCookie* CookieParser::parseOneCookie(const String& cookie, unsigned start,
 
     if (hasName)
         res->setValue(value);
-    else if (foundEqual) {
-        delete res;
+    else if (foundEqual)
         return 0;
-    else
+    else
         res->setName(value); // No NAME=VALUE, only NAME
 
     while (pairEnd < end) {
@@ -250,7 +248,7 @@ ParsedCookie* CookieParser::parseOneCookie(const String& cookie, unsigned start,
 #if 0
                 // Check if path attribute is a prefix of the request URI.
                 if (!m_defaultCookieURL.path().startsWith(res->path()))
-                    LOG_AND_DELETE("Invalid cookie attribute %s (path): it does not math the URL", cookie.ascii().data());
+                    LOG_ERROR_AND_RETURN("Invalid cookie attribute %s (path): it does not math the URL", cookie.ascii().data());
 #endif
             } else
                 LOG_ERROR("Invalid cookie attribute %s (path)", cookie.ascii().data());
@@ -266,7 +264,7 @@ ParsedCookie* CookieParser::parseOneCookie(const String& cookie, unsigned start,
                 // Check if the domain contains an embedded dot.
                 size_t dotPosition = parsedValue.find(".", 1);
                 if (dotPosition == notFound || dotPosition == parsedValue.length())
-                    LOG_AND_DELETE("Invalid cookie attribute %s (domain): it does not contain an embedded dot", cookie.ascii().data());
+                    LOG_ERROR_AND_RETURN("Invalid cookie attribute %s (domain): it does not contain an embedded dot", cookie.ascii().data());
 
                 // If the domain does not start with a dot, add one for security checks,
                 // For example: ab.c.com dose not domain match b.c.com;
@@ -282,7 +280,7 @@ ParsedCookie* CookieParser::parseOneCookie(const String& cookie, unsigned start,
                 if (m_defaultDomainIsIPAddress) {
                     String realDomainCanonical = String(BlackBerry::Platform::getCanonicalIPFormat(realDomain.utf8().data()).c_str());
                     if (realDomainCanonical.isEmpty() || realDomainCanonical != m_defaultCookieHost)
-                        LOG_AND_DELETE("Invalid cookie attribute %s (domain): domain is IP but does not match host's IP", cookie.ascii().data());
+                        LOG_ERROR_AND_RETURN("Invalid cookie attribute %s (domain): domain is IP but does not match host's IP", cookie.ascii().data());
                     realDomain = realDomainCanonical;
                     isIPAddress = true;
                 } else {
@@ -294,14 +292,14 @@ ParsedCookie* CookieParser::parseOneCookie(const String& cookie, unsigned start,
                     // We also have to make a special case for IP addresses. If a website tries to set
                     // a cookie to 61.97, that domain is not an IP address and will end with the m_defaultCookieHost
                     if (!m_defaultCookieHost.endsWith(realDomain, false))
-                        LOG_AND_DELETE("Invalid cookie attribute %s (domain): it does not domain match the host", cookie.ascii().data());
+                        LOG_ERROR_AND_RETURN("Invalid cookie attribute %s (domain): it does not domain match the host", cookie.ascii().data());
                     // We should check for an embedded dot in the portion of string in the host not in the domain
                     // but to match firefox behaviour we do not.
 
                     // Check whether the domain is a top level domain, if it is throw it out
                     // http://publicsuffix.org/list/
                     if (BlackBerry::Platform::isTopLevelDomain(realDomain.utf8().data()))
-                        LOG_AND_DELETE("Invalid cookie attribute %s (domain): it did not pass the top level domain check", cookie.ascii().data());
+                        LOG_ERROR_AND_RETURN("Invalid cookie attribute %s (domain): it did not pass the top level domain check", cookie.ascii().data());
                 }
                 res->setDomain(realDomain, isIPAddress);
             } else
@@ -347,7 +345,7 @@ ParsedCookie* CookieParser::parseOneCookie(const String& cookie, unsigned start,
                     parsedValue = parsedValue.substring(1, parsedValue.length() - 2);
 
                 if (parsedValue.toInt() != 1)
-                    LOG_AND_DELETE("ParsedCookie version %d not supported (only support version=1)", parsedValue.toInt());
+                    LOG_ERROR_AND_RETURN("ParsedCookie version %d not supported (only support version=1)", parsedValue.toInt());
             } else
                 LOG_ERROR("Invalid cookie attribute %s (version)", cookie.ascii().data());
             break;
@@ -382,7 +380,7 @@ ParsedCookie* CookieParser::parseOneCookie(const String& cookie, unsigned start,
 
     // Check if the cookie is valid with respect to the size limit.
     if (!res->isUnderSizeLimit())
-        LOG_AND_DELETE("ParsedCookie %s is above the 4kb in length : REJECTED", cookie.ascii().data());
+        LOG_ERROR_AND_RETURN("ParsedCookie %s is above the 4kb in length : REJECTED", cookie.ascii().data());
 
     // If some pair was not provided, during parsing then apply some default value
     // the rest has been done in the constructor.
index aed5e87..c944f86 100644 (file)
@@ -43,13 +43,13 @@ public:
     ~CookieParser();
 
     // Parses a sequence of "Cookie:" header and return the parsed cookies.
-    Vector<ParsedCookie*> parse(const String& cookies);
+    Vector<RefPtr<ParsedCookie> > parse(const String& cookies);
 
-    ParsedCookie* parseOneCookie(const String& cookie);
+    PassRefPtr<ParsedCookie> parseOneCookie(const String& cookie);
 
 private:
     // FIXME: curTime, start, end parameters should be removed. And this method can be public.
-    ParsedCookie* parseOneCookie(const String& cookie, unsigned start, unsigned end, double curTime);
+    PassRefPtr<ParsedCookie> parseOneCookie(const String& cookie, unsigned start, unsigned end, double curTime);
 
     KURL m_defaultCookieURL;
     String m_defaultCookieHost;
index c449fc6..bff8de0 100644 (file)
@@ -66,27 +66,6 @@ ParsedCookie::ParsedCookie(const String& name, const String& value, const String
 {
 }
 
-ParsedCookie::ParsedCookie(const ParsedCookie* cookie)
-    : m_name(String(cookie->m_name))
-    , m_value(String(cookie->m_value))
-    , m_domain(String(cookie->m_domain))
-    , m_protocol(String(cookie->m_protocol))
-    , m_path(String(cookie->m_path))
-    , m_expiry(cookie->m_expiry)
-    , m_creationTime(cookie->m_creationTime)
-    , m_lastAccessed(cookie->m_lastAccessed)
-    , m_isSecure(cookie->m_isSecure)
-    , m_isHttpOnly(cookie->m_isHttpOnly)
-    , m_isSession(cookie->m_isSession)
-    , m_isForceExpired(cookie->m_isForceExpired)
-    , m_domainIsIPAddress(cookie->m_domainIsIPAddress)
-{
-}
-
-ParsedCookie::~ParsedCookie()
-{
-}
-
 void ParsedCookie::setExpiry(const String& expiry)
 {
     // If a cookie has both the Max-Age and the Expires attribute,
index 9db7549..1bccec6 100644 (file)
@@ -28,7 +28,9 @@
 #define ParsedCookie_h
 
 #include "Cookie.h"
-#include <wtf/FastAllocBase.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
 
 namespace WTF {
 class String;
@@ -40,18 +42,14 @@ class KURL;
 // This class represents a cookie internally
 // It can either be created by the CookieParser which will then fill it
 // or it can be created by the backing store filling it in the constructor.
-class ParsedCookie {
-WTF_MAKE_FAST_ALLOCATED;
+class ParsedCookie : public RefCounted<ParsedCookie> {
 public:
+
     // Default cookie : empty domain, non secure and session
-    ParsedCookie(double currentTime);
+    static PassRefPtr<ParsedCookie> create(double currentTime) { return adoptRef(new ParsedCookie(currentTime)); }
 
     // For backing store cookies (those cookies are never session cookies).
-    ParsedCookie(const String& name, const String& value, const String& domain, const String& protocol, const String& path, double expiry, double lastAccessed, double creationTime, bool isSecure, bool isHttpOnly);
-
-    ParsedCookie(const ParsedCookie*);
-
-    ~ParsedCookie();
+    static PassRefPtr<ParsedCookie> create(const String& name, const String& value, const String& domain, const String& protocol, const String& path, double expiry, double lastAccessed, double creationTime, bool isSecure, bool isHttpOnly)  { return adoptRef(new ParsedCookie(name, value, domain, protocol, path, expiry, lastAccessed, creationTime, isSecure, isHttpOnly)); };
 
     const String& name() const { return m_name; }
     void setName(const String& name) { m_name = name; }
@@ -97,6 +95,12 @@ public:
     void appendWebCoreCookie(Vector<Cookie>& cookieVector) const;
 
 private:
+    // Default cookie : empty domain, non secure and session
+    ParsedCookie(double currentTime);
+
+    // For backing store cookies (those cookies are never session cookies).
+    ParsedCookie(const String& name, const String& value, const String& domain, const String& protocol, const String& path, double expiry, double lastAccessed, double creationTime, bool isSecure, bool isHttpOnly);
+
     String m_name;
     String m_value;
     String m_domain;
index 796f59b..b3ba8f3 100644 (file)
@@ -37,7 +37,7 @@ std::vector<BlackBerry::Platform::String> WebCookieJar::cookies(const BlackBerry
 {
     KURL kurl = KURL(KURL(), url);
 
-    Vector<ParsedCookie*> rawCookies;
+    Vector<RefPtr<ParsedCookie> > rawCookies;
     cookieManager().getRawCookies(rawCookies, kurl, WithHttpOnlyCookies);
 
     std::vector<BlackBerry::Platform::String> result;
index 4dabd58..fb8069f 100644 (file)
@@ -1,3 +1,15 @@
+2013-03-07  Otto Derek Cheung  <otcheung@rim.com>
+
+        [BlackBerry] RefCounting ParsedCookie to avoid SegFaults
+        https://bugs.webkit.org/show_bug.cgi?id=111761
+
+        Reviewed by Rob Buis.
+
+        Making necessary changes to ref-count the ParsedCookie object.
+
+        * Api/WebCookieJar.cpp:
+        (BlackBerry::WebKit::WebCookieJar::cookies):
+
 2013-03-07  Mike Fenton  <mifenton@rim.com>
 
         [BlackBerry] Prevent text selection inside Colour and Date/Time input fields