Bug 1641270 - Part 3: Make nsICookieJarSetting serializable. r=dimi

In order to send the cookieJarSetting across processes in JS. We need to
make it serializable.

Differential Revision: https://phabricator.services.mozilla.com/D95613
This commit is contained in:
Tim Huang 2020-11-11 11:13:55 +00:00
parent a2f2e35e51
commit fd15d2199a
5 changed files with 211 additions and 2 deletions

View File

@ -603,6 +603,13 @@ Classes = [
'constructor': 'mozilla::net::GetSFVService',
'headers': ['mozilla/net/SFVService.h'],
},
{
'cid': '{4ce234f1-52e8-47a9-8c8d-b02f815733c7}',
'contract_ids': ['@mozilla.org/cookieJarSettings;1'],
'type': 'nsICookieJarSettings',
'constructor': 'mozilla::net::CookieJarSettings::Create',
'headers': ['mozilla/net/CookieJarSettings.h'],
},
]
if defined('NECKO_WIFI'):

View File

@ -20,13 +20,21 @@
#if defined(MOZ_THUNDERBIRD) || defined(MOZ_SUITE)
# include "nsIProtocolHandler.h"
#endif
#include "nsIClassInfoImpl.h"
#include "nsICookieManager.h"
#include "nsICookieService.h"
#include "nsIObjectInputStream.h"
#include "nsIObjectOutputStream.h"
#include "nsNetUtil.h"
namespace mozilla {
namespace net {
NS_IMPL_CLASSINFO(CookieJarSettings, nullptr, nsIClassInfo::THREADSAFE,
COOKIEJARSETTINGS_CID)
NS_IMPL_ISUPPORTS_CI(CookieJarSettings, nsICookieJarSettings, nsISerializable)
static StaticRefPtr<CookieJarSettings> sBlockinAll;
namespace {
@ -466,7 +474,146 @@ bool CookieJarSettings::IsRejectThirdPartyWithExceptions(
StaticPrefs::network_cookie_rejectForeignWithExceptions_enabled();
}
NS_IMPL_ISUPPORTS(CookieJarSettings, nsICookieJarSettings)
NS_IMETHODIMP
CookieJarSettings::Read(nsIObjectInputStream* aStream) {
nsresult rv = aStream->Read32(&mCookieBehavior);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = aStream->ReadBoolean(&mIsFirstPartyIsolated);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
bool isFixed;
aStream->ReadBoolean(&isFixed);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
mState = isFixed ? eFixed : eProgressive;
rv = aStream->ReadBoolean(&mIsOnContentBlockingAllowList);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = aStream->ReadString(mPartitionKey);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// Deserializing the cookie permission list.
uint32_t cookiePermissionsLength;
rv = aStream->Read32(&cookiePermissionsLength);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (!cookiePermissionsLength) {
// Bailing out early because there is no cookie permission.
return NS_OK;
}
CookiePermissionList list;
mCookiePermissions.SetCapacity(cookiePermissionsLength);
for (uint32_t i = 0; i < cookiePermissionsLength; ++i) {
nsAutoCString principalJSON;
aStream->ReadCString(principalJSON);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsCOMPtr<nsIPrincipal> principal = BasePrincipal::FromJSON(principalJSON);
if (NS_WARN_IF(!principal)) {
continue;
}
uint32_t cookiePermission;
aStream->Read32(&cookiePermission);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsCOMPtr<nsIPermission> permission =
Permission::Create(principal, "cookie"_ns, cookiePermission, 0, 0, 0);
if (NS_WARN_IF(!permission)) {
continue;
}
list.AppendElement(permission);
}
mCookiePermissions = std::move(list);
return NS_OK;
}
NS_IMETHODIMP
CookieJarSettings::Write(nsIObjectOutputStream* aStream) {
nsresult rv = aStream->Write32(mCookieBehavior);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = aStream->WriteBoolean(mIsFirstPartyIsolated);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = aStream->WriteBoolean(mState == eFixed);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = aStream->WriteBoolean(mIsOnContentBlockingAllowList);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = aStream->WriteWStringZ(mPartitionKey.get());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// Serializing the cookie permission list. It will first write the length of
// the list, and then, write the cookie permission consecutively.
uint32_t cookiePermissionsLength = mCookiePermissions.Length();
rv = aStream->Write32(cookiePermissionsLength);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
for (const RefPtr<nsIPermission>& permission : mCookiePermissions) {
nsCOMPtr<nsIPrincipal> principal;
nsresult rv = permission->GetPrincipal(getter_AddRefs(principal));
if (NS_WARN_IF(NS_FAILED(rv))) {
continue;
}
nsAutoCString principalJSON;
BasePrincipal::Cast(principal)->ToJSON(principalJSON);
rv = aStream->WriteStringZ(principalJSON.get());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
uint32_t cookiePermission = 0;
rv = permission->GetCapability(&cookiePermission);
if (NS_WARN_IF(NS_FAILED(rv))) {
continue;
}
rv = aStream->Write32(cookiePermission);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
return NS_OK;
}
} // namespace net
} // namespace mozilla

View File

@ -11,6 +11,15 @@
#include "nsDataHashtable.h"
#include "nsTArray.h"
#define COOKIEJARSETTINGS_CONTRACTID "@mozilla.org/cookieJarSettings;1"
// 4ce234f1-52e8-47a9-8c8d-b02f815733c7
#define COOKIEJARSETTINGS_CID \
{ \
0x4ce234f1, 0x52e8, 0x47a9, { \
0x8c, 0x8d, 0xb0, 0x2f, 0x81, 0x57, 0x33, 0xc7 \
} \
}
class nsIPermission;
namespace mozilla {
@ -111,6 +120,7 @@ class CookieJarSettings final : public nsICookieJarSettings {
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSICOOKIEJARSETTINGS
NS_DECL_NSISERIALIZABLE
static already_AddRefed<nsICookieJarSettings> GetBlockingAll();

View File

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
#include "nsISerializable.idl"
interface nsIPrincipal;
@ -13,7 +14,7 @@ interface nsIPrincipal;
* for more details.
*/
[scriptable, builtinclass, uuid(3ec40331-7cf0-4b71-ba2a-2265aab8f6bc)]
interface nsICookieJarSettings : nsISupports
interface nsICookieJarSettings : nsISerializable
{
/**
* CookieBehavior at the loading of the document. Any other loadInfo

View File

@ -814,6 +814,50 @@ var E10SUtils = {
return fallbackPrincipalCallback();
},
/**
* Serialize cookieJarSettings.
*
* @param {nsICookieJarSettings} cookieJarSettings The cookieJarSettings to
* serialize.
* @return {String} The base64 encoded cookieJarSettings data.
*/
serializeCookieJarSettings(cookieJarSettings) {
let serialized = null;
if (cookieJarSettings) {
try {
serialized = serializationHelper.serializeToString(cookieJarSettings);
} catch (e) {
this.log().error(
`Failed to serialize cookieJarSettings '${cookieJarSettings}' ${e}`
);
}
}
return serialized;
},
/**
* Deserialize a base64 encoded cookieJarSettings
*
* @param {String} cookieJarSettings_b64 A base64 encoded serialized cookieJarSettings.
* @return {nsICookieJarSettings} A deserialized cookieJarSettings.
*/
deserializeCookieJarSettings(cookieJarSettings_b64) {
let deserialized = null;
if (cookieJarSettings_b64) {
try {
deserialized = serializationHelper.deserializeObject(
cookieJarSettings_b64
);
deserialized.QueryInterface(Ci.nsICookieJarSettings);
} catch (e) {
this.log().error(
`Failed to deserialize cookieJarSettings_b64 '${cookieJarSettings_b64}' ${e}`
);
}
}
return deserialized;
},
/**
* Returns whether or not a URI is supposed to load in a particular
* browser given its current remote type.